@xtctwins/tctwins-core 1.0.32 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tctwins-core.es.js +3319 -3317
- package/dist/tctwins-core.min.es.js +5 -5
- package/package.json +1 -1
|
@@ -2404,7 +2404,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
2404
2404
|
\******************************************/
|
|
2405
2405
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2406
2406
|
|
|
2407
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MetaModel: () => (/* binding */ MetaModel)\n/* harmony export */ });\n/* harmony import */ var _PropertySet_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PropertySet.js */ \"./src/viewer/metadata/PropertySet.js\");\n/* harmony import */ var _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MetaObject.js */ \"./src/viewer/metadata/MetaObject.js\");\n/* harmony import */ var _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\n/**\r\n * @desc Metadata corresponding to an {@link Entity} that represents a model.\r\n *\r\n * An {@link Entity} represents a model when {@link Entity#isModel} is ````true````\r\n *\r\n * A MetaModel corresponds to an {@link Entity} by having the same {@link MetaModel#id} as the {@link Entity#id}.\r\n *\r\n * A MetaModel is created by {@link MetaScene#createMetaModel} and belongs to a {@link MetaScene}.\r\n *\r\n * Each MetaModel is registered by {@link MetaModel#id} in {@link MetaScene#metaModels}.\r\n *\r\n * A {@link MetaModel} represents its object structure with a tree of {@link MetaObject}s, with {@link MetaModel#rootMetaObject} referencing the root {@link MetaObject}.\r\n *\r\n * @class MetaModel\r\n */\r\nclass MetaModel {\r\n\t/**\r\n\t * Creates a new, unfinalized MetaModel.\r\n\t *\r\n\t * * The MetaModel is immediately registered by {@link MetaModel#id} in {@link MetaScene#metaModels}, even though it's not yet populated.\r\n\t * * The MetaModel then needs to be populated with one or more calls to {@link metaModel#loadData}.\r\n\t * * As we populate it, the MetaModel will create {@link MetaObject}s and {@link PropertySet}s in itself, and in the MetaScene.\r\n\t * * When populated, call {@link MetaModel#finalize} to finish it off, which causes MetaScene to fire a \"metaModelCreated\" event.\r\n\t */\r\n\tconstructor(params) {\r\n\t\t/**\r\n\t\t * Globally-unique ID.\r\n\t\t *\r\n\t\t * MetaModels are registered by ID in {@link MetaScene#metaModels}.\r\n\t\t *\r\n\t\t * When this MetaModel corresponds to an {@link Entity} then this ID will match the {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property id\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.id = params.id;\r\n\r\n\t\t/**\r\n\t\t * The project ID\r\n\t\t * @property projectId\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.projectId = params.projectId;\r\n\r\n\t\t/**\r\n\t\t * The revision ID, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property revisionId\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.revisionId = params.revisionId;\r\n\r\n\t\t/**\r\n\t\t * The model author, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property author\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.author = params.author;\r\n\r\n\t\t/**\r\n\t\t * The date the model was created, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property createdAt\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.createdAt = params.createdAt;\r\n\r\n\t\t/**\r\n\t\t * The application that created the model, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property creatingApplication\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.creatingApplication = params.creatingApplication;\r\n\r\n\t\t/**\r\n\t\t * The model schema version, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property schema\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.schema = params.schema;\r\n\r\n\t\t/**\r\n\t\t * Metadata on the {@link Scene}.\r\n\t\t *\r\n\t\t * @property metaScene\r\n\t\t * @type {MetaScene}\r\n\t\t */\r\n\t\tthis.metaScene = params.metaScene;\r\n\r\n\t\t/**\r\n\t\t * The {@link PropertySet}s in this MetaModel.\r\n\t\t *\r\n\t\t * @property propertySets\r\n\t\t * @type {PropertySet[]}\r\n\t\t */\r\n\t\tthis.propertySets = [];\r\n\r\n\t\t/**\r\n\t\t * The root {@link MetaObject}s in this MetaModel's composition structure hierarchy.\r\n\t\t *\r\n\t\t * @property rootMetaObject\r\n\t\t * @type {MetaObject[]}\r\n\t\t */\r\n\t\tthis.rootMetaObjects = [];\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s in this MetaModel, each mapped to its ID.\r\n\t\t *\r\n\t\t * @property metaObjects\r\n\t\t * @type {MetaObject[]}\r\n\t\t */\r\n\t\tthis.metaObjects = [];\r\n\r\n\t\tthis.objectCount = 0;\r\n\t\tthis.propertySetCount = 0;\r\n\r\n\t\t/**\r\n\t\t * Connectivity graph.\r\n\t\t * @type {{}}\r\n\t\t */\r\n\t\tthis.graph = params.graph || {};\r\n\r\n\t\tthis.metaScene.metaModels[this.id] = this;\r\n\r\n\t\t/**\r\n\t\t * True when this MetaModel has been finalized.\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\tthis._finalized = false;\r\n\t}\r\n\r\n\tset finalized(finalized) {\r\n\t\tthis._finalized = finalized;\r\n\t}\r\n\r\n\tget finalized() {\r\n\t\treturn this._finalized;\r\n\t}\r\n\r\n\t/**\r\n\t * Backwards compatibility with the model having a single root MetaObject.\r\n\t *\r\n\t * @property rootMetaObject\r\n\t * @type {MetaObject|null}\r\n\t */\r\n\tget rootMetaObject() {\r\n\t\tif (this.rootMetaObjects.length == 1) {\r\n\t\t\treturn this.rootMetaObjects[0];\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\t/**\r\n\t * Load metamodel data into this MetaModel.\r\n\t * @param metaModelData\r\n\t */\r\n\t// loadData(metaModelData, options = {}) {\r\n\tloadData(metaModelData, done, err) {\r\n\t\tif (this._finalized) {\r\n\t\t\tthrow \"MetaScene already finalized - can't add more data\";\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tif (metaModelData.author) this.author = metaModelData.author;\r\n\t\t\tif (metaModelData.schema) this.schema = metaModelData.schema;\r\n\t\t\tif (metaModelData.createdAt) this.createdAt = metaModelData.createdAt;\r\n\t\t\tif (metaModelData.projectId) this.projectId = metaModelData.projectId;\r\n\t\t\tif (metaModelData.revisionId) this.revisionId = metaModelData.revisionId;\r\n\t\t\tif (metaModelData.objectCount) this.objectCount = metaModelData.objectCount;\r\n\t\t\tif (metaModelData.propertySetCount) this.propertySetCount = metaModelData.propertySetCount;\r\n\t\t\tif (metaModelData.creatingApplication) this.creatingApplication = metaModelData.creatingApplication;\r\n\r\n\t\t\t// this._globalizeIDs(metaModelData, options);\r\n\r\n\t\t\tconst metaScene = this.metaScene;\r\n\r\n\t\t\tif (metaModelData.propertySets) {\r\n\t\t\t\t// for (let i = 0; i < metaModelData.propertySets.length; i++) {\r\n\t\t\t\t// \tconst propertySetData = metaModelData.propertySets[i];\r\n\t\t\t\t// const metaId = propertySetData.id;\r\n\r\n\t\t\t\tfor (let metaId in metaModelData.propertySets) {\r\n\t\t\t\t\tconst propertySetData = metaModelData.propertySets[metaId];\r\n\t\t\t\t\tlet propertySet = new _PropertySet_js__WEBPACK_IMPORTED_MODULE_0__.PropertySet({\r\n\t\t\t\t\t\tid: propertySetData.id,\r\n\t\t\t\t\t\toriginalSystemId: propertySetData.originalSystemId || propertySetData.id,\r\n\t\t\t\t\t\ttype: propertySetData.type,\r\n\t\t\t\t\t\tname: propertySetData.name,\r\n\t\t\t\t\t\tproperties: propertySetData.properties\r\n\t\t\t\t\t});\r\n\t\t\t\t\tmetaScene.propertySets[metaId] = propertySet;\r\n\t\t\t\t\t// propertySet.metaModels.push(this);\r\n\t\t\t\t\tthis.propertySets.push(propertySet);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (metaModelData.metaObjects) {\r\n\t\t\t\t// for (let i = 0; i < metaModelData.metaObjects.length; i++) {\r\n\t\t\t\t// \tconst objectData = metaModelData.metaObjects[i];\r\n\t\t\t\t// \tconst metaId = objectData.id;\r\n\r\n\t\t\t\tfor (let metaId in metaModelData.metaObjects) {\r\n\t\t\t\t\tconst objectData = metaModelData.metaObjects[metaId];\r\n\t\t\t\t\tlet metaObject = new _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__.MetaObject({\r\n\t\t\t\t\t\tid: metaId,\r\n\t\t\t\t\t\toriginalSystemId: metaId,\r\n\t\t\t\t\t\tparentId: objectData.parent,\r\n\t\t\t\t\t\ttype: objectData.type,\r\n\t\t\t\t\t\tname: objectData.name,\r\n\t\t\t\t\t\tpropertySetIds: objectData.propertySetIds,\r\n\t\t\t\t\t\texternal: objectData.external\r\n\t\t\t\t\t});\r\n\t\t\t\t\tmetaObject.children = [];\r\n\t\t\t\t\tmetaObject.metaModels = [];\r\n\t\t\t\t\tmetaObject.metaModels.push(this);\r\n\t\t\t\t\tmetaScene.metaObjects[metaId] = metaObject;\r\n\r\n\t\t\t\t\tthis.metaObjects.push(metaObject);\r\n\t\t\t\t\tif (!objectData.parent) {\r\n\t\t\t\t\t\tthis.rootMetaObjects.push(metaObject);\r\n\t\t\t\t\t\tmetaScene.rootMetaObjects[metaId] = metaObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (typeof done === \"function\") done();\r\n\t\t} catch (error) {\r\n\t\t\tif (typeof err === \"function\") err(error);\r\n\t\t\telse this.log(err);\r\n\t\t}\r\n\t}\r\n\r\n\t_decompressProperties(propertyLookup, properties) {\r\n\t\tfor (let i = 0, len = properties.length; i < len; i++) {\r\n\t\t\tconst property = properties[i];\r\n\t\t\tif (Number.isInteger(property)) {\r\n\t\t\t\tconst lookupProperty = propertyLookup[property];\r\n\t\t\t\tif (lookupProperty) {\r\n\t\t\t\t\tproperties[i] = lookupProperty;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfinalize() {\r\n\t\tif (this._finalized) {\r\n\t\t\tthrow \"MetaScene already finalized - can't re-finalize\";\r\n\t\t}\r\n\r\n\t\t// Re-link MetaScene's entire MetaObject parent/child hierarchy\r\n\r\n\t\tconst metaScene = this.metaScene;\r\n\t\tmetaScene.metaObjectsByType = {};\r\n\r\n\t\tfor (let objectId in metaScene.metaObjects) {\r\n\t\t\tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t\t// if (metaObject.children) {\r\n\t\t\t// \tmetaObject.children = [];\r\n\t\t\t// }\r\n\t\t\tif (metaObject.parentId) {\r\n\t\t\t\tconst parentMetaObject = metaScene.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\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 = metaScene.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\r\n\t\t\tconst type = metaObject.type;\r\n\t\t\t(metaScene.metaObjectsByType[type] || (metaScene.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t}\r\n\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tif (metaObject.parentId) {\r\n\t\t// \t\tconst parentMetaObject = metaScene.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\t// Relink MetaObjects to their MetaModels\r\n\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tmetaObject.metaModels = [];\r\n\t\t// }\r\n\r\n\t\t// for (let modelId in metaScene.metaModels) {\r\n\t\t// \tconst metaModel = metaScene.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\t// Rebuild MetaScene's MetaObjects-by-type lookup\r\n\r\n\t\t// metaScene.metaObjectsByType = {};\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tconst type = metaObject.type;\r\n\t\t// \t(metaScene.metaObjectsByType[type] || (metaScene.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t// }\r\n\r\n\t\tthis._finalized = true;\r\n\r\n\t\tthis.metaScene.fire(\"metaModelCreated\", this.id);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets this MetaModel as JSON.\r\n\t * @returns {{schema: (String|string|*), createdAt: (String|string|*), metaObjects: *[], author: (String|string|*), id: (String|Number|string|number|*), creatingApplication: (String|string|*), projectId: (String|Number|string|number|*), propertySets: *[]}}\r\n\t */\r\n\tgetJSON() {\r\n\t\tconst json = {\r\n\t\t\tid: this.id,\r\n\t\t\tprojectId: this.projectId,\r\n\t\t\tauthor: this.author,\r\n\t\t\tcreatedAt: this.createdAt,\r\n\t\t\tschema: this.schema,\r\n\t\t\tcreatingApplication: this.creatingApplication,\r\n\t\t\tmetaObjects: [],\r\n\t\t\tpropertySets: []\r\n\t\t};\r\n\t\tfor (let i = 0, len = this.metaObjects.length; i < len; i++) {\r\n\t\t\tconst metaObject = this.metaObjects[i];\r\n\t\t\tconst metaObjectCfg = {\r\n\t\t\t\tid: metaObject.id,\r\n\t\t\t\toriginalSystemId: metaObject.originalSystemId,\r\n\t\t\t\textId: metaObject.extId,\r\n\t\t\t\ttype: metaObject.type,\r\n\t\t\t\tname: metaObject.name\r\n\t\t\t};\r\n\t\t\tif (metaObject.parent) {\r\n\t\t\t\tmetaObjectCfg.parent = metaObject.parent.id;\r\n\t\t\t}\r\n\t\t\tif (metaObject.attributes) {\r\n\t\t\t\tmetaObjectCfg.attributes = metaObject.attributes;\r\n\t\t\t}\r\n\t\t\tif (metaObject.propertySetIds) {\r\n\t\t\t\tmetaObjectCfg.propertySetIds = metaObject.propertySetIds;\r\n\t\t\t}\r\n\t\t\tjson.metaObjects.push(metaObjectCfg);\r\n\t\t}\r\n\t\tfor (let i = 0, len = this.propertySets.length; i < len; i++) {\r\n\t\t\tconst propertySet = this.propertySets[i];\r\n\t\t\tconst propertySetCfg = {\r\n\t\t\t\tid: propertySet.id,\r\n\t\t\t\toriginalSystemId: propertySet.originalSystemId,\r\n\t\t\t\textId: propertySet.extId,\r\n\t\t\t\ttype: propertySet.type,\r\n\t\t\t\tname: propertySet.name,\r\n\t\t\t\tpropertyies: []\r\n\t\t\t};\r\n\t\t\tfor (let j = 0, lenj = propertySet.properties.length; j < lenj; j++) {\r\n\t\t\t\tconst property = propertySet.properties[j];\r\n\t\t\t\tconst propertyCfg = {\r\n\t\t\t\t\tid: property.id,\r\n\t\t\t\t\tdescription: property.description,\r\n\t\t\t\t\ttype: property.type,\r\n\t\t\t\t\tname: property.name,\r\n\t\t\t\t\tvalue: property.value,\r\n\t\t\t\t\tvalueType: property.valueType\r\n\t\t\t\t};\r\n\t\t\t\tpropertySetCfg.properties.push(propertyCfg);\r\n\t\t\t}\r\n\t\t\tjson.propertySets.push(propertySetCfg);\r\n\t\t}\r\n\t\treturn json;\r\n\t}\r\n\r\n\t_globalizeIDs(metaModelData, options) {\r\n\t\tconst globalize = !!options.globalizeObjectIds;\r\n\r\n\t\tif (metaModelData.metaObjects) {\r\n\t\t\tfor (let i = 0, len = metaModelData.metaObjects.length; i < len; i++) {\r\n\t\t\t\tconst metaObjectData = metaModelData.metaObjects[i];\r\n\r\n\t\t\t\t// Globalize MetaObject IDs and parent IDs\r\n\r\n\t\t\t\tmetaObjectData.originalSystemId = metaObjectData.id;\r\n\t\t\t\tif (metaObjectData.parent) {\r\n\t\t\t\t\tmetaObjectData.originalParentSystemId = metaObjectData.parent;\r\n\t\t\t\t}\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tmetaObjectData.id = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, metaObjectData.id);\r\n\t\t\t\t\tif (metaObjectData.parent) {\r\n\t\t\t\t\t\tmetaObjectData.parent = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, metaObjectData.parent);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Globalize MetaObject property set IDs\r\n\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tconst propertySetIds = metaObjectData.propertySetIds;\r\n\t\t\t\t\tif (propertySetIds) {\r\n\t\t\t\t\t\tconst propertySetGlobalIds = [];\r\n\t\t\t\t\t\tfor (let j = 0, lenj = propertySetIds.length; j < lenj; j++) {\r\n\t\t\t\t\t\t\tpropertySetGlobalIds.push(_scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, propertySetIds[j]));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tmetaObjectData.propertySetIds = propertySetGlobalIds;\r\n\t\t\t\t\t\tmetaObjectData.originalSystemPropertySetIds = propertySetIds;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tmetaObjectData.originalSystemPropertySetIds = metaObjectData.propertySetIds;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Globalize global PropertySet IDs\r\n\r\n\t\tif (metaModelData.propertySets) {\r\n\t\t\tfor (let i = 0, len = metaModelData.propertySets.length; i < len; i++) {\r\n\t\t\t\tconst propertySet = metaModelData.propertySets[i];\r\n\t\t\t\tpropertySet.originalSystemId = propertySet.id;\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tpropertySet.id = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, propertySet.id);\r\n\t\t\t\t}\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/metadata/MetaModel.js?");
|
|
2407
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MetaModel: () => (/* binding */ MetaModel)\n/* harmony export */ });\n/* harmony import */ var _PropertySet_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PropertySet.js */ \"./src/viewer/metadata/PropertySet.js\");\n/* harmony import */ var _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MetaObject.js */ \"./src/viewer/metadata/MetaObject.js\");\n/* harmony import */ var _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\n/**\r\n * @desc Metadata corresponding to an {@link Entity} that represents a model.\r\n *\r\n * An {@link Entity} represents a model when {@link Entity#isModel} is ````true````\r\n *\r\n * A MetaModel corresponds to an {@link Entity} by having the same {@link MetaModel#id} as the {@link Entity#id}.\r\n *\r\n * A MetaModel is created by {@link MetaScene#createMetaModel} and belongs to a {@link MetaScene}.\r\n *\r\n * Each MetaModel is registered by {@link MetaModel#id} in {@link MetaScene#metaModels}.\r\n *\r\n * A {@link MetaModel} represents its object structure with a tree of {@link MetaObject}s, with {@link MetaModel#rootMetaObject} referencing the root {@link MetaObject}.\r\n *\r\n * @class MetaModel\r\n */\r\nclass MetaModel {\r\n\t/**\r\n\t * Creates a new, unfinalized MetaModel.\r\n\t *\r\n\t * * The MetaModel is immediately registered by {@link MetaModel#id} in {@link MetaScene#metaModels}, even though it's not yet populated.\r\n\t * * The MetaModel then needs to be populated with one or more calls to {@link metaModel#loadData}.\r\n\t * * As we populate it, the MetaModel will create {@link MetaObject}s and {@link PropertySet}s in itself, and in the MetaScene.\r\n\t * * When populated, call {@link MetaModel#finalize} to finish it off, which causes MetaScene to fire a \"metaModelCreated\" event.\r\n\t */\r\n\tconstructor(params) {\r\n\t\t/**\r\n\t\t * Globally-unique ID.\r\n\t\t *\r\n\t\t * MetaModels are registered by ID in {@link MetaScene#metaModels}.\r\n\t\t *\r\n\t\t * When this MetaModel corresponds to an {@link Entity} then this ID will match the {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property id\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.id = params.id;\r\n\r\n\t\t/**\r\n\t\t * The project ID\r\n\t\t * @property projectId\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.projectId = params.projectId;\r\n\r\n\t\t/**\r\n\t\t * The revision ID, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property revisionId\r\n\t\t * @type {String|Number}\r\n\t\t */\r\n\t\tthis.revisionId = params.revisionId;\r\n\r\n\t\t/**\r\n\t\t * The model author, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property author\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.author = params.author;\r\n\r\n\t\t/**\r\n\t\t * The date the model was created, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property createdAt\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.createdAt = params.createdAt;\r\n\r\n\t\t/**\r\n\t\t * The application that created the model, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property creatingApplication\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.creatingApplication = params.creatingApplication;\r\n\r\n\t\t/**\r\n\t\t * The model schema version, if available.\r\n\t\t *\r\n\t\t * Will be undefined if not available.\r\n\t\t *\r\n\t\t * @property schema\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.schema = params.schema;\r\n\r\n\t\t/**\r\n\t\t * Metadata on the {@link Scene}.\r\n\t\t *\r\n\t\t * @property metaScene\r\n\t\t * @type {MetaScene}\r\n\t\t */\r\n\t\tthis.metaScene = params.metaScene;\r\n\r\n\t\t/**\r\n\t\t * The {@link PropertySet}s in this MetaModel.\r\n\t\t *\r\n\t\t * @property propertySets\r\n\t\t * @type {PropertySet[]}\r\n\t\t */\r\n\t\tthis.propertySets = [];\r\n\r\n\t\t/**\r\n\t\t * The root {@link MetaObject}s in this MetaModel's composition structure hierarchy.\r\n\t\t *\r\n\t\t * @property rootMetaObject\r\n\t\t * @type {MetaObject[]}\r\n\t\t */\r\n\t\tthis.rootMetaObjects = [];\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s in this MetaModel, each mapped to its ID.\r\n\t\t *\r\n\t\t * @property metaObjects\r\n\t\t * @type {MetaObject[]}\r\n\t\t */\r\n\t\tthis.metaObjects = [];\r\n\r\n\t\tthis.objectCount = 0;\r\n\t\tthis.propertySetCount = 0;\r\n\r\n\t\t/**\r\n\t\t * Connectivity graph.\r\n\t\t * @type {{}}\r\n\t\t */\r\n\t\tthis.graph = params.graph || {};\r\n\r\n\t\tthis.metaScene.metaModels[this.id] = this;\r\n\r\n\t\t/**\r\n\t\t * True when this MetaModel has been finalized.\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\tthis._finalized = false;\r\n\t}\r\n\r\n\tset finalized(finalized) {\r\n\t\tthis._finalized = finalized;\r\n\t}\r\n\r\n\tget finalized() {\r\n\t\treturn this._finalized;\r\n\t}\r\n\r\n\t/**\r\n\t * Backwards compatibility with the model having a single root MetaObject.\r\n\t *\r\n\t * @property rootMetaObject\r\n\t * @type {MetaObject|null}\r\n\t */\r\n\tget rootMetaObject() {\r\n\t\tif (this.rootMetaObjects.length == 1) {\r\n\t\t\treturn this.rootMetaObjects[0];\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\t/**\r\n\t * Load metamodel data into this MetaModel.\r\n\t * @param metaModelData\r\n\t */\r\n\t// loadData(metaModelData, options = {}) {\r\n\tloadData(metaModelData, done, err) {\r\n\t\tif (this._finalized) {\r\n\t\t\tthrow \"MetaScene already finalized - can't add more data\";\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tif (metaModelData === null) throw \"metaModelData is null!\";\r\n\t\t\t// 使用可选链和空值合并\r\n\t\t\tthis.author = metaModelData.author ?? \"\";\r\n\t\t\tthis.schema = metaModelData.schema ?? \"\";\r\n\t\t\tthis.createdAt = metaModelData.createdAt ?? \"\";\r\n\t\t\tthis.projectId = metaModelData.projectId ?? \"\";\r\n\t\t\tthis.revisionId = metaModelData.revisionId ?? \"\";\r\n\t\t\tthis.objectCount = metaModelData.objectCount ?? \"\";\r\n\t\t\tthis.propertySetCount = metaModelData.propertySetCount ?? \"\";\r\n\t\t\tthis.creatingApplication = metaModelData.creatingApplication ?? \"\";\r\n\r\n\t\t\t// this._globalizeIDs(metaModelData, options);\r\n\r\n\t\t\tconst metaScene = this.metaScene;\r\n\r\n\t\t\tif (metaModelData.propertySets) {\r\n\t\t\t\t// for (let i = 0; i < metaModelData.propertySets.length; i++) {\r\n\t\t\t\t// \tconst propertySetData = metaModelData.propertySets[i];\r\n\t\t\t\t// const metaId = propertySetData.id;\r\n\r\n\t\t\t\tfor (let metaId in metaModelData.propertySets) {\r\n\t\t\t\t\tconst propertySetData = metaModelData.propertySets[metaId];\r\n\t\t\t\t\tlet propertySet = new _PropertySet_js__WEBPACK_IMPORTED_MODULE_0__.PropertySet({\r\n\t\t\t\t\t\tid: propertySetData.id,\r\n\t\t\t\t\t\toriginalSystemId: propertySetData.originalSystemId || propertySetData.id,\r\n\t\t\t\t\t\ttype: propertySetData.type,\r\n\t\t\t\t\t\tname: propertySetData.name,\r\n\t\t\t\t\t\tproperties: propertySetData.properties\r\n\t\t\t\t\t});\r\n\t\t\t\t\tmetaScene.propertySets[metaId] = propertySet;\r\n\t\t\t\t\t// propertySet.metaModels.push(this);\r\n\t\t\t\t\tthis.propertySets.push(propertySet);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (metaModelData.metaObjects) {\r\n\t\t\t\t// for (let i = 0; i < metaModelData.metaObjects.length; i++) {\r\n\t\t\t\t// \tconst objectData = metaModelData.metaObjects[i];\r\n\t\t\t\t// \tconst metaId = objectData.id;\r\n\r\n\t\t\t\tfor (let metaId in metaModelData.metaObjects) {\r\n\t\t\t\t\tconst objectData = metaModelData.metaObjects[metaId];\r\n\t\t\t\t\tlet metaObject = new _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__.MetaObject({\r\n\t\t\t\t\t\tid: metaId,\r\n\t\t\t\t\t\toriginalSystemId: metaId,\r\n\t\t\t\t\t\tparentId: objectData.parent,\r\n\t\t\t\t\t\ttype: objectData.type,\r\n\t\t\t\t\t\tname: objectData.name,\r\n\t\t\t\t\t\tpropertySetIds: objectData.propertySetIds,\r\n\t\t\t\t\t\texternal: objectData.external\r\n\t\t\t\t\t});\r\n\t\t\t\t\tmetaObject.children = [];\r\n\t\t\t\t\tmetaObject.metaModels = [];\r\n\t\t\t\t\tmetaObject.metaModels.push(this);\r\n\t\t\t\t\tmetaScene.metaObjects[metaId] = metaObject;\r\n\r\n\t\t\t\t\tthis.metaObjects.push(metaObject);\r\n\t\t\t\t\tif (!objectData.parent) {\r\n\t\t\t\t\t\tthis.rootMetaObjects.push(metaObject);\r\n\t\t\t\t\t\tmetaScene.rootMetaObjects[metaId] = metaObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (typeof done === \"function\") done();\r\n\t\t} catch (error) {\r\n\t\t\tif (typeof err === \"function\") err(error);\r\n\t\t\telse this.log(err);\r\n\t\t}\r\n\t}\r\n\r\n\t_decompressProperties(propertyLookup, properties) {\r\n\t\tfor (let i = 0, len = properties.length; i < len; i++) {\r\n\t\t\tconst property = properties[i];\r\n\t\t\tif (Number.isInteger(property)) {\r\n\t\t\t\tconst lookupProperty = propertyLookup[property];\r\n\t\t\t\tif (lookupProperty) {\r\n\t\t\t\t\tproperties[i] = lookupProperty;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfinalize() {\r\n\t\tif (this._finalized) {\r\n\t\t\tthrow \"MetaScene already finalized - can't re-finalize\";\r\n\t\t}\r\n\r\n\t\t// Re-link MetaScene's entire MetaObject parent/child hierarchy\r\n\r\n\t\tconst metaScene = this.metaScene;\r\n\t\tmetaScene.metaObjectsByType = {};\r\n\r\n\t\tfor (let objectId in metaScene.metaObjects) {\r\n\t\t\tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t\t// if (metaObject.children) {\r\n\t\t\t// \tmetaObject.children = [];\r\n\t\t\t// }\r\n\t\t\tif (metaObject.parentId) {\r\n\t\t\t\tconst parentMetaObject = metaScene.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\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 = metaScene.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\r\n\t\t\tconst type = metaObject.type;\r\n\t\t\t(metaScene.metaObjectsByType[type] || (metaScene.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t}\r\n\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tif (metaObject.parentId) {\r\n\t\t// \t\tconst parentMetaObject = metaScene.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\t// Relink MetaObjects to their MetaModels\r\n\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tmetaObject.metaModels = [];\r\n\t\t// }\r\n\r\n\t\t// for (let modelId in metaScene.metaModels) {\r\n\t\t// \tconst metaModel = metaScene.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\t// Rebuild MetaScene's MetaObjects-by-type lookup\r\n\r\n\t\t// metaScene.metaObjectsByType = {};\r\n\t\t// for (let objectId in metaScene.metaObjects) {\r\n\t\t// \tconst metaObject = metaScene.metaObjects[objectId];\r\n\t\t// \tconst type = metaObject.type;\r\n\t\t// \t(metaScene.metaObjectsByType[type] || (metaScene.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t// }\r\n\r\n\t\tthis._finalized = true;\r\n\r\n\t\tthis.metaScene.fire(\"metaModelCreated\", this.id);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets this MetaModel as JSON.\r\n\t * @returns {{schema: (String|string|*), createdAt: (String|string|*), metaObjects: *[], author: (String|string|*), id: (String|Number|string|number|*), creatingApplication: (String|string|*), projectId: (String|Number|string|number|*), propertySets: *[]}}\r\n\t */\r\n\tgetJSON() {\r\n\t\tconst json = {\r\n\t\t\tid: this.id,\r\n\t\t\tprojectId: this.projectId,\r\n\t\t\tauthor: this.author,\r\n\t\t\tcreatedAt: this.createdAt,\r\n\t\t\tschema: this.schema,\r\n\t\t\tcreatingApplication: this.creatingApplication,\r\n\t\t\tmetaObjects: [],\r\n\t\t\tpropertySets: []\r\n\t\t};\r\n\t\tfor (let i = 0, len = this.metaObjects.length; i < len; i++) {\r\n\t\t\tconst metaObject = this.metaObjects[i];\r\n\t\t\tconst metaObjectCfg = {\r\n\t\t\t\tid: metaObject.id,\r\n\t\t\t\toriginalSystemId: metaObject.originalSystemId,\r\n\t\t\t\textId: metaObject.extId,\r\n\t\t\t\ttype: metaObject.type,\r\n\t\t\t\tname: metaObject.name\r\n\t\t\t};\r\n\t\t\tif (metaObject.parent) {\r\n\t\t\t\tmetaObjectCfg.parent = metaObject.parent.id;\r\n\t\t\t}\r\n\t\t\tif (metaObject.attributes) {\r\n\t\t\t\tmetaObjectCfg.attributes = metaObject.attributes;\r\n\t\t\t}\r\n\t\t\tif (metaObject.propertySetIds) {\r\n\t\t\t\tmetaObjectCfg.propertySetIds = metaObject.propertySetIds;\r\n\t\t\t}\r\n\t\t\tjson.metaObjects.push(metaObjectCfg);\r\n\t\t}\r\n\t\tfor (let i = 0, len = this.propertySets.length; i < len; i++) {\r\n\t\t\tconst propertySet = this.propertySets[i];\r\n\t\t\tconst propertySetCfg = {\r\n\t\t\t\tid: propertySet.id,\r\n\t\t\t\toriginalSystemId: propertySet.originalSystemId,\r\n\t\t\t\textId: propertySet.extId,\r\n\t\t\t\ttype: propertySet.type,\r\n\t\t\t\tname: propertySet.name,\r\n\t\t\t\tpropertyies: []\r\n\t\t\t};\r\n\t\t\tfor (let j = 0, lenj = propertySet.properties.length; j < lenj; j++) {\r\n\t\t\t\tconst property = propertySet.properties[j];\r\n\t\t\t\tconst propertyCfg = {\r\n\t\t\t\t\tid: property.id,\r\n\t\t\t\t\tdescription: property.description,\r\n\t\t\t\t\ttype: property.type,\r\n\t\t\t\t\tname: property.name,\r\n\t\t\t\t\tvalue: property.value,\r\n\t\t\t\t\tvalueType: property.valueType\r\n\t\t\t\t};\r\n\t\t\t\tpropertySetCfg.properties.push(propertyCfg);\r\n\t\t\t}\r\n\t\t\tjson.propertySets.push(propertySetCfg);\r\n\t\t}\r\n\t\treturn json;\r\n\t}\r\n\r\n\t_globalizeIDs(metaModelData, options) {\r\n\t\tconst globalize = !!options.globalizeObjectIds;\r\n\r\n\t\tif (metaModelData.metaObjects) {\r\n\t\t\tfor (let i = 0, len = metaModelData.metaObjects.length; i < len; i++) {\r\n\t\t\t\tconst metaObjectData = metaModelData.metaObjects[i];\r\n\r\n\t\t\t\t// Globalize MetaObject IDs and parent IDs\r\n\r\n\t\t\t\tmetaObjectData.originalSystemId = metaObjectData.id;\r\n\t\t\t\tif (metaObjectData.parent) {\r\n\t\t\t\t\tmetaObjectData.originalParentSystemId = metaObjectData.parent;\r\n\t\t\t\t}\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tmetaObjectData.id = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, metaObjectData.id);\r\n\t\t\t\t\tif (metaObjectData.parent) {\r\n\t\t\t\t\t\tmetaObjectData.parent = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, metaObjectData.parent);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Globalize MetaObject property set IDs\r\n\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tconst propertySetIds = metaObjectData.propertySetIds;\r\n\t\t\t\t\tif (propertySetIds) {\r\n\t\t\t\t\t\tconst propertySetGlobalIds = [];\r\n\t\t\t\t\t\tfor (let j = 0, lenj = propertySetIds.length; j < lenj; j++) {\r\n\t\t\t\t\t\t\tpropertySetGlobalIds.push(_scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, propertySetIds[j]));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tmetaObjectData.propertySetIds = propertySetGlobalIds;\r\n\t\t\t\t\t\tmetaObjectData.originalSystemPropertySetIds = propertySetIds;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tmetaObjectData.originalSystemPropertySetIds = metaObjectData.propertySetIds;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Globalize global PropertySet IDs\r\n\r\n\t\tif (metaModelData.propertySets) {\r\n\t\t\tfor (let i = 0, len = metaModelData.propertySets.length; i < len; i++) {\r\n\t\t\t\tconst propertySet = metaModelData.propertySets[i];\r\n\t\t\t\tpropertySet.originalSystemId = propertySet.id;\r\n\t\t\t\tif (globalize) {\r\n\t\t\t\t\tpropertySet.id = _scene_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.globalizeObjectId(this.id, propertySet.id);\r\n\t\t\t\t}\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/metadata/MetaModel.js?");
|
|
2408
2408
|
|
|
2409
2409
|
/***/ }),
|
|
2410
2410
|
|
|
@@ -2514,7 +2514,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
2514
2514
|
\***************************************************************************/
|
|
2515
2515
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2516
2516
|
|
|
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\tthis._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?");
|
|
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?");
|
|
2518
2518
|
|
|
2519
2519
|
/***/ }),
|
|
2520
2520
|
|
|
@@ -2734,7 +2734,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
2734
2734
|
\*******************************************/
|
|
2735
2735
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2736
2736
|
|
|
2737
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Canvas: () => (/* binding */ Canvas)\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 _Spinner_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Spinner.js */ \"./src/viewer/scene/canvas/Spinner.js\");\n\r\n\r\n\r\n\r\nconst WEBGL_CONTEXT_NAMES = [\"webgl2\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\", \"moz-glweb20\"];\r\n\r\n/**\r\n * @desc Manages its {@link Scene}'s HTML canvas.\r\n *\r\n * * Provides the HTML canvas element in {@link Canvas#canvas}.\r\n * * Has a {@link Spinner}, provided at {@link Canvas#spinner}, which manages the loading progress indicator.\r\n */\r\nclass Canvas extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\r\n\t/**\r\n\t * @constructor\r\n\t * @private\r\n\t */\r\n\tconstructor(owner, cfg = {}) {\r\n\t\tsuper(owner, cfg);\r\n\t\tthis._backgroundColor = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([\r\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[0] : 1,\r\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[1] : 1,\r\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[2] : 1\r\n\t\t]);\r\n\t\tthis._backgroundColorFromAmbientLight = !!cfg.backgroundColorFromAmbientLight;\r\n\r\n\t\tthis.parent = owner;\r\n\t\tif (cfg.canvas)\r\n\t\t\t/**\r\n\t\t\t * The HTML canvas.\r\n\t\t\t *\r\n\t\t\t * @property canvas\r\n\t\t\t * @type {HTMLCanvasElement}\r\n\t\t\t * @final\r\n\t\t\t */\r\n\t\t\tthis.canvas = cfg.canvas;\r\n\t\telse this._createCanvas();\r\n\r\n\t\t/**\r\n\t\t * The WebGL rendering context.\r\n\t\t *\r\n\t\t * @property gl\r\n\t\t * @type {WebGLRenderingContext}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.gl = null;\r\n\r\n\t\t/**\r\n\t\t * True when WebGL 2 support is enabled.\r\n\t\t *\r\n\t\t * @property webgl2\r\n\t\t * @type {Boolean}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.webgl2 = false; // Will set true in _initWebGL if WebGL is requested and we succeed in getting it.\r\n\r\n\t\t/**\r\n\t\t * Indicates if this Canvas is transparent.\r\n\t\t *\r\n\t\t * @property transparent\r\n\t\t * @type {Boolean}\r\n\t\t * @default {false}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.transparent = !!cfg.transparent;\r\n\r\n\t\t/**\r\n\t\t * Attributes for the WebGL context\r\n\t\t *\r\n\t\t * @type {{}|*}\r\n\t\t */\r\n\t\tthis.contextAttr = cfg.contextAttr || {};\r\n\t\tthis.contextAttr.alpha = this.transparent;\r\n\r\n\t\tthis.contextAttr.preserveDrawingBuffer = !!this.contextAttr.preserveDrawingBuffer;\r\n\t\tthis.contextAttr.stencil = false;\r\n\t\tthis.contextAttr.premultipliedAlpha = !!this.contextAttr.premultipliedAlpha; // False by default: https://github.com/xeokit/xeokit-sdk/issues/251\r\n\t\tthis.contextAttr.antialias = this.contextAttr.antialias !== false;\r\n\r\n\t\t// If the canvas uses css styles to specify the sizes make sure the basic\r\n\t\t// width and height attributes match or the WebGL context will use 300 x 150\r\n\r\n\t\tthis.resolutionScale = cfg.resolutionScale;\r\n\r\n\t\tthis.canvas.width = Math.round(this.canvas.clientWidth * this._resolutionScale);\r\n\t\tthis.canvas.height = Math.round(this.canvas.clientHeight * this._resolutionScale);\r\n\r\n\t\t/**\r\n\t\t * Boundary of the Canvas in absolute browser window coordinates.\r\n\t\t *\r\n\t\t * ### Usage:\r\n\t\t *\r\n\t\t * ````javascript\r\n\t\t * var boundary = myScene.canvas.boundary;\r\n\t\t *\r\n\t\t * var xmin = boundary[0];\r\n\t\t * var ymin = boundary[1];\r\n\t\t * var width = boundary[2];\r\n\t\t * var height = boundary[3];\r\n\t\t * ````\r\n\t\t *\r\n\t\t * @property boundary\r\n\t\t * @type {Number[]}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.boundary = [this.canvas.left, this.canvas.offsetTop, this.canvas.clientWidth, this.canvas.clientHeight];\r\n\r\n\t\t// Get WebGL context\r\n\t\tthis._initWebGL();\r\n\r\n\t\t// Bind context loss and recovery handlers\r\n\r\n\t\tconst self = this;\r\n\r\n\t\tthis.canvas.addEventListener(\r\n\t\t\t\"webglcontextlost\",\r\n\t\t\t(this._webglcontextlostListener = function (event) {\r\n\t\t\t\tconsole.time(\"webglcontextrestored\");\r\n\t\t\t\tself.scene._webglContextLost();\r\n\t\t\t\t/**\r\n\t\t\t\t * Fired whenever the WebGL context has been lost\r\n\t\t\t\t * @event webglcontextlost\r\n\t\t\t\t */\r\n\t\t\t\tself.fire(\"webglcontextlost\");\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t}),\r\n\t\t\tfalse\r\n\t\t);\r\n\r\n\t\tthis.canvas.addEventListener(\r\n\t\t\t\"webglcontextrestored\",\r\n\t\t\t(this._webglcontextrestoredListener = function (event) {\r\n\t\t\t\tself._initWebGL();\r\n\t\t\t\tif (self.gl) {\r\n\t\t\t\t\tself.scene._webglContextRestored(self.gl);\r\n\t\t\t\t\t/**\r\n\t\t\t\t\t * Fired whenever the WebGL context has been restored again after having previously being lost\r\n\t\t\t\t\t * @event webglContextRestored\r\n\t\t\t\t\t * @param value The WebGL context object\r\n\t\t\t\t\t */\r\n\t\t\t\t\tself.fire(\"webglcontextrestored\", self.gl);\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t}\r\n\t\t\t\tconsole.timeEnd(\"webglcontextrestored\");\r\n\t\t\t}),\r\n\t\t\tfalse\r\n\t\t);\r\n\r\n\t\t// Attach to resize events on the canvas\r\n\t\tthis._dirtyBoundary = true; // make sure we publish the 1st boundary event\r\n\r\n\t\tconst resizeObserver = new ResizeObserver((entries) => {\r\n\t\t\tfor (const entry of entries) {\r\n\t\t\t\tif (entry.contentBoxSize) {\r\n\t\t\t\t\tthis._dirtyBoundary = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tresizeObserver.observe(this.canvas);\r\n\r\n\t\t// Publish canvas size and position changes on each scene tick\r\n\t\tthis._tick = this.scene.on(\"tick\", () => {\r\n\t\t\t// Only publish if the canvas bounds changed\r\n\t\t\tif (!this._dirtyBoundary) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis._dirtyBoundary = false;\r\n\r\n\t\t\t// Set the real size of the canvas (the drawable w*h)\r\n\t\t\tself.canvas.width = Math.round(self.canvas.clientWidth * self._resolutionScale);\r\n\t\t\tself.canvas.height = Math.round(self.canvas.clientHeight * self._resolutionScale);\r\n\r\n\t\t\t// Publish the boundary change\r\n\t\t\tself.boundary[0] = self.canvas.offsetLeft;\r\n\t\t\tself.boundary[1] = self.canvas.offsetTop;\r\n\t\t\tself.boundary[2] = self.canvas.clientWidth;\r\n\t\t\tself.boundary[3] = self.canvas.clientHeight;\r\n\r\n\t\t\tself.fire(\"boundary\", self.boundary);\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\t * @type {Spinner}\r\n\t\t */\r\n\t\tthis._spinner = new _Spinner_js__WEBPACK_IMPORTED_MODULE_2__.Spinner(this.scene, {\r\n\t\t\tcanvas: this.canvas,\r\n\t\t\telementId: cfg.spinnerElementId\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 设置是否需要改变canvas\r\n\t * @param {boolean} change\r\n\t */\r\n\tset dirtyBoundary(change) {\r\n\t\tthis._dirtyBoundary = change;\r\n\t}\r\n\r\n\t/**\r\n @private\r\n */\r\n\tget type() {\r\n\t\treturn \"Canvas\";\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the canvas clear color will be derived from {@link AmbientLight} or {@link Canvas#backgroundColor}\r\n\t * when {@link Canvas#transparent} is ```true```.\r\n\t *\r\n\t * When {@link Canvas#transparent} is ```true``` and this is ````true````, then the canvas clear color will\r\n\t * be taken from the {@link Scene}'s ambient light color.\r\n\t *\r\n\t * When {@link Canvas#transparent} is ```true``` and this is ````false````, then the canvas clear color will\r\n\t * be taken from {@link Canvas#backgroundColor}.\r\n\t *\r\n\t * Default value is ````true````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tget backgroundColorFromAmbientLight() {\r\n\t\treturn this._backgroundColorFromAmbientLight;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if the canvas background color is derived from an {@link AmbientLight}.\r\n\t *\r\n\t * This only has effect when the canvas is not transparent. When not enabled, the background color\r\n\t * will be the canvas element's HTML/CSS background color.\r\n\t *\r\n\t * Default value is ````true````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tset backgroundColorFromAmbientLight(backgroundColorFromAmbientLight) {\r\n\t\tthis._backgroundColorFromAmbientLight = backgroundColorFromAmbientLight !== false;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the canvas clear color.\r\n\t *\r\n\t * Default value is ````[1, 1, 1]````.\r\n\t *\r\n\t * @type {Number[]}\r\n\t */\r\n\tget backgroundColor() {\r\n\t\treturn this._backgroundColor;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the canvas clear color.\r\n\t *\r\n\t * Default value is ````[1, 1, 1]````.\r\n\t *\r\n\t * @type {Number[]}\r\n\t */\r\n\tset backgroundColor(value) {\r\n\t\tif (value) {\r\n\t\t\tthis._backgroundColor[0] = value[0];\r\n\t\t\tthis._backgroundColor[1] = value[1];\r\n\t\t\tthis._backgroundColor[2] = value[2];\r\n\t\t} else {\r\n\t\t\tthis._backgroundColor[0] = 1.0;\r\n\t\t\tthis._backgroundColor[1] = 1.0;\r\n\t\t\tthis._backgroundColor[2] = 1.0;\r\n\t\t}\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\r\n\t *\r\n\t * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\r\n\t * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\r\n\t * a performance boost.\r\n\t *\r\n\t * @returns {*|number} The resolution scale.\r\n\t */\r\n\tget resolutionScale() {\r\n\t\treturn this._resolutionScale;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\r\n\t *\r\n\t * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\r\n\t * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\r\n\t * a performance boost.\r\n\t *\r\n\t * @param {*|number} resolutionScale The resolution scale.\r\n\t */\r\n\tset resolutionScale(resolutionScale) {\r\n\t\tresolutionScale = resolutionScale || 1.0;\r\n\t\tif (resolutionScale === this._resolutionScale) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._resolutionScale = resolutionScale;\r\n\t\tconst canvas = this.canvas;\r\n\t\tcanvas.width = Math.round(canvas.clientWidth * this._resolutionScale);\r\n\t\tcanvas.height = Math.round(canvas.clientHeight * this._resolutionScale);\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * The busy {@link Spinner} for this Canvas.\r\n\t *\r\n\t * @property spinner\r\n\t * @type Spinner\r\n\t * @final\r\n\t */\r\n\tget spinner() {\r\n\t\treturn this._spinner;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a default canvas in the DOM.\r\n\t * @private\r\n\t */\r\n\t_createCanvas() {\r\n\t\tconst canvasId = \"tctwins-canvas-\" + _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.createUUID();\r\n\t\tconst div = document.createElement(\"div\");\r\n\r\n\t\tconst style = div.style;\r\n\t\tstyle.height = \"100%\";\r\n\t\tstyle.width = \"100%\";\r\n\t\tstyle.padding = \"0\";\r\n\t\tstyle.margin = \"0\";\r\n\t\tstyle.background = \"rgba(0,0,0,0);\";\r\n\t\tstyle.float = \"left\";\r\n\t\tstyle.left = \"0\";\r\n\t\tstyle.top = \"0\";\r\n\t\tstyle.position = \"absolute\";\r\n\t\tstyle.opacity = \"1.0\";\r\n\t\tstyle[\"z-index\"] = \"-10000\";\r\n\r\n\t\tdiv.innerHTML +=\r\n\t\t\t'<canvas id=\"' + canvasId + '\" style=\"width: 100%; height: 100%; float: left; margin: 0; padding: 0;\"></canvas>';\r\n\r\n\t\tthis.parent.viewer.container.appendChild(div);\r\n\t\tthis.canvas = document.getElementById(canvasId);\r\n\t}\r\n\r\n\t_getElementXY(e) {\r\n\t\tlet x = 0,\r\n\t\t\ty = 0;\r\n\t\twhile (e) {\r\n\t\t\tx += e.offsetLeft - e.scrollLeft;\r\n\t\t\ty += e.offsetTop - e.scrollTop;\r\n\t\t\te = e.offsetParent;\r\n\t\t}\r\n\t\treturn { x: x, y: y };\r\n\t}\r\n\r\n\t/**\r\n\t * Initialises the WebGL context\r\n\t * @private\r\n\t */\r\n\t_initWebGL() {\r\n\t\t// Default context attribute values\r\n\r\n\t\tif (!this.gl) {\r\n\t\t\tfor (let i = 0; !this.gl && i < WEBGL_CONTEXT_NAMES.length; i++) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tthis.gl = this.canvas.getContext(WEBGL_CONTEXT_NAMES[i], this.contextAttr);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t// Try with next context name\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.gl) {\r\n\t\t\tthis.error(\"Failed to get a WebGL context\");\r\n\r\n\t\t\t/**\r\n\t\t\t * Fired whenever the canvas failed to get a WebGL context, which probably means that WebGL\r\n\t\t\t * is either unsupported or has been disabled.\r\n\t\t\t * @event webglContextFailed\r\n\t\t\t */\r\n\t\t\tthis.fire(\"webglContextFailed\", true, true);\r\n\t\t}\r\n\r\n\t\t// data-textures: avoid to re-bind same texture\r\n\t\t{\r\n\t\t\tconst gl = this.gl;\r\n\r\n\t\t\tlet lastTextureUnit = \"__\";\r\n\r\n\t\t\tlet originalActiveTexture = gl.activeTexture;\r\n\r\n\t\t\tgl.activeTexture = function (arg1) {\r\n\t\t\t\tif (lastTextureUnit === arg1) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlastTextureUnit = arg1;\r\n\r\n\t\t\t\toriginalActiveTexture.call(this, arg1);\r\n\t\t\t};\r\n\r\n\t\t\tlet lastBindTexture = {};\r\n\r\n\t\t\tlet originalBindTexture = gl.bindTexture;\r\n\r\n\t\t\tlet avoidedRebinds = 0;\r\n\r\n\t\t\tgl.bindTexture = function (arg1, arg2) {\r\n\t\t\t\tif (lastBindTexture[lastTextureUnit] === arg2) {\r\n\t\t\t\t\tavoidedRebinds++;\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlastBindTexture[lastTextureUnit] = arg2;\r\n\r\n\t\t\t\toriginalBindTexture.call(this, arg1, arg2);\r\n\t\t\t};\r\n\r\n\t\t\t// setInterval (\r\n\t\t\t// () => {\r\n\t\t\t// console.log (`${avoidedRebinds} avoided texture binds/sec`);\r\n\t\t\t// avoidedRebinds = 0;\r\n\t\t\t// },\r\n\t\t\t// 1000\r\n\t\t\t// );\r\n\t\t}\r\n\r\n\t\tif (this.gl) {\r\n\t\t\t// Setup extension (if necessary) and hints for fragment shader derivative functions\r\n\t\t\tif (this.webgl2) {\r\n\t\t\t\tthis.gl.hint(this.gl.FRAGMENT_SHADER_DERIVATIVE_HINT, this.gl.FASTEST);\r\n\r\n\t\t\t\t// data-textures: not using standard-derivatives\r\n\t\t\t\tif (!(this.gl instanceof WebGL2RenderingContext)) {\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t * @deprecated\r\n\t */\r\n\tgetSnapshot(params) {\r\n\t\tthrow \"Canvas#getSnapshot() has been replaced by Viewer#getSnapshot() - use that method instead.\";\r\n\t}\r\n\r\n\t/**\r\n\t * Reads colors of pixels from the last rendered frame.\r\n\t *\r\n\t * Call this method like this:\r\n\t *\r\n\t * ````JavaScript\r\n\t *\r\n\t * // Ignore transparent pixels (default is false)\r\n\t * var opaqueOnly = true;\r\n\t *\r\n\t * var colors = new Float32Array(8);\r\n\t *\r\n\t * viewer.scene.canvas.readPixels([ 100, 22, 12, 33 ], colors, 2, opaqueOnly);\r\n\t * ````\r\n\t *\r\n\t * Then the r,g,b components of the colors will be set to the colors at those pixels.\r\n\t *\r\n\t * @param {Number[]} pixels\r\n\t * @param {Number[]} colors\r\n\t * @param {Number} size\r\n\t * @param {Boolean} opaqueOnly\r\n\t */\r\n\treadPixels(pixels, colors, size, opaqueOnly) {\r\n\t\treturn this.scene._renderer.readPixels(pixels, colors, size, opaqueOnly);\r\n\t}\r\n\r\n\t/**\r\n\t * Simulates lost WebGL context.\r\n\t */\r\n\tloseWebGLContext() {\r\n\t\tif (this.canvas.loseContext) {\r\n\t\t\tthis.canvas.loseContext();\r\n\t\t}\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tthis.scene.off(this._tick);\r\n\t\tif (this._spinner) {\r\n\t\t\tthis._spinner.destroy();\r\n\t\t\tthis._spinner = null;\r\n\t\t}\r\n\t\t// Memory leak avoidance\r\n\t\tthis.canvas.removeEventListener(\"webglcontextlost\", this._webglcontextlostListener);\r\n\t\tthis.canvas.removeEventListener(\"webglcontextrestored\", this._webglcontextrestoredListener);\r\n\t\tif (this.gl != null) {\r\n\t\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);\r\n\t\t\tthis.gl = null;\r\n\t\t}\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/canvas/Canvas.js?");
|
|
2737
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Canvas: () => (/* binding */ Canvas)\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 _Spinner_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Spinner.js */ \"./src/viewer/scene/canvas/Spinner.js\");\n\n\n\n\nconst WEBGL_CONTEXT_NAMES = [\"webgl2\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\", \"moz-glweb20\"];\n\n/**\n * @desc Manages its {@link Scene}'s HTML canvas.\n *\n * * Provides the HTML canvas element in {@link Canvas#canvas}.\n * * Has a {@link Spinner}, provided at {@link Canvas#spinner}, which manages the loading progress indicator.\n */\nclass Canvas extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\n\t/**\n\t * @constructor\n\t * @private\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\t\tthis._backgroundColor = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[0] : 1,\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[1] : 1,\n\t\t\tcfg.backgroundColor ? cfg.backgroundColor[2] : 1\n\t\t]);\n\t\tthis._backgroundColorFromAmbientLight = !!cfg.backgroundColorFromAmbientLight;\n\n\t\tthis.parent = owner;\n\t\tif (cfg.canvas)\n\t\t\t/**\n\t\t\t * The HTML canvas.\n\t\t\t *\n\t\t\t * @property canvas\n\t\t\t * @type {HTMLCanvasElement}\n\t\t\t * @final\n\t\t\t */\n\t\t\tthis.canvas = cfg.canvas;\n\t\telse this._createCanvas();\n\n\t\t/**\n\t\t * The WebGL rendering context.\n\t\t *\n\t\t * @property gl\n\t\t * @type {WebGLRenderingContext}\n\t\t * @final\n\t\t */\n\t\tthis.gl = null;\n\n\t\t/**\n\t\t * True when WebGL 2 support is enabled.\n\t\t *\n\t\t * @property webgl2\n\t\t * @type {Boolean}\n\t\t * @final\n\t\t */\n\t\tthis.webgl2 = false; // Will set true in _initWebGL if WebGL is requested and we succeed in getting it.\n\n\t\t/**\n\t\t * Indicates if this Canvas is transparent.\n\t\t *\n\t\t * @property transparent\n\t\t * @type {Boolean}\n\t\t * @default {false}\n\t\t * @final\n\t\t */\n\t\tthis.transparent = !!cfg.transparent;\n\n\t\t/**\n\t\t * Attributes for the WebGL context\n\t\t *\n\t\t * @type {{}|*}\n\t\t */\n\t\tthis.contextAttr = cfg.contextAttr || {};\n\t\tthis.contextAttr.alpha = this.transparent;\n\n\t\tthis.contextAttr.preserveDrawingBuffer = !!this.contextAttr.preserveDrawingBuffer;\n\t\tthis.contextAttr.stencil = false;\n\t\tthis.contextAttr.premultipliedAlpha = !!this.contextAttr.premultipliedAlpha; // False by default: https://github.com/xeokit/xeokit-sdk/issues/251\n\t\tthis.contextAttr.antialias = this.contextAttr.antialias !== false;\n\n\t\t// If the canvas uses css styles to specify the sizes make sure the basic\n\t\t// width and height attributes match or the WebGL context will use 300 x 150\n\n\t\tthis.resolutionScale = cfg.resolutionScale;\n\n\t\tthis.canvas.width = Math.round(this.canvas.clientWidth * this._resolutionScale);\n\t\tthis.canvas.height = Math.round(this.canvas.clientHeight * this._resolutionScale);\n\n\t\t/**\n\t\t * Boundary of the Canvas in absolute browser window coordinates.\n\t\t *\n\t\t * ### Usage:\n\t\t *\n\t\t * ````javascript\n\t\t * var boundary = myScene.canvas.boundary;\n\t\t *\n\t\t * var xmin = boundary[0];\n\t\t * var ymin = boundary[1];\n\t\t * var width = boundary[2];\n\t\t * var height = boundary[3];\n\t\t * ````\n\t\t *\n\t\t * @property boundary\n\t\t * @type {Number[]}\n\t\t * @final\n\t\t */\n\t\tthis.boundary = [this.canvas.left, this.canvas.offsetTop, this.canvas.clientWidth, this.canvas.clientHeight];\n\n\t\t// Get WebGL context\n\t\tthis._initWebGL();\n\n\t\t// Bind context loss and recovery handlers\n\n\t\tconst self = this;\n\n\t\tthis.canvas.addEventListener(\n\t\t\t\"webglcontextlost\",\n\t\t\t(this._webglcontextlostListener = function (event) {\n\t\t\t\tconsole.time(\"webglcontextrestored\");\n\t\t\t\tself.scene._webglContextLost();\n\t\t\t\t/**\n\t\t\t\t * Fired whenever the WebGL context has been lost\n\t\t\t\t * @event webglcontextlost\n\t\t\t\t */\n\t\t\t\tself.fire(\"webglcontextlost\");\n\t\t\t\tevent.preventDefault();\n\t\t\t}),\n\t\t\tfalse\n\t\t);\n\n\t\tthis.canvas.addEventListener(\n\t\t\t\"webglcontextrestored\",\n\t\t\t(this._webglcontextrestoredListener = function (event) {\n\t\t\t\tself._initWebGL();\n\t\t\t\tif (self.gl) {\n\t\t\t\t\tself.scene._webglContextRestored(self.gl);\n\t\t\t\t\t/**\n\t\t\t\t\t * Fired whenever the WebGL context has been restored again after having previously being lost\n\t\t\t\t\t * @event webglContextRestored\n\t\t\t\t\t * @param value The WebGL context object\n\t\t\t\t\t */\n\t\t\t\t\tself.fire(\"webglcontextrestored\", self.gl);\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t\tconsole.timeEnd(\"webglcontextrestored\");\n\t\t\t}),\n\t\t\tfalse\n\t\t);\n\n\t\t// Attach to resize events on the canvas\n\t\tthis._dirtyBoundary = true; // make sure we publish the 1st boundary event\n\n\t\tconst resizeObserver = new ResizeObserver((entries) => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (entry.contentBoxSize) {\n\t\t\t\t\tthis._dirtyBoundary = true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tresizeObserver.observe(this.canvas);\n\n\t\t// Publish canvas size and position changes on each scene tick\n\t\tthis._tick = this.scene.on(\"tick\", () => {\n\t\t\t// Only publish if the canvas bounds changed\n\t\t\tif (!this._dirtyBoundary) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._dirtyBoundary = false;\n\n\t\t\t// Set the real size of the canvas (the drawable w*h)\n\t\t\tself.canvas.width = Math.round(self.canvas.clientWidth * self._resolutionScale);\n\t\t\tself.canvas.height = Math.round(self.canvas.clientHeight * self._resolutionScale);\n\n\t\t\t// Publish the boundary change\n\t\t\tself.boundary[0] = self.canvas.offsetLeft;\n\t\t\tself.boundary[1] = self.canvas.offsetTop;\n\t\t\tself.boundary[2] = self.canvas.clientWidth;\n\t\t\tself.boundary[3] = self.canvas.clientHeight;\n\n\t\t\tself.fire(\"boundary\", self.boundary);\n\t\t});\n\n\t\t/**\n\t\t * @type {Spinner}\n\t\t */\n\t\tthis._spinner = new _Spinner_js__WEBPACK_IMPORTED_MODULE_2__.Spinner(this.scene, {\n\t\t\tcanvas: this.canvas,\n\t\t\telementId: cfg.spinnerElementId\n\t\t});\n\t}\n\n\t/**\n\t * 设置是否需要改变canvas\n\t * @param {boolean} change\n\t */\n\tset dirtyBoundary(change) {\n\t\tthis._dirtyBoundary = change;\n\t}\n\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"Canvas\";\n\t}\n\n\t/**\n\t * Gets whether the canvas clear color will be derived from {@link AmbientLight} or {@link Canvas#backgroundColor}\n\t * when {@link Canvas#transparent} is ```true```.\n\t *\n\t * When {@link Canvas#transparent} is ```true``` and this is ````true````, then the canvas clear color will\n\t * be taken from the {@link Scene}'s ambient light color.\n\t *\n\t * When {@link Canvas#transparent} is ```true``` and this is ````false````, then the canvas clear color will\n\t * be taken from {@link Canvas#backgroundColor}.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget backgroundColorFromAmbientLight() {\n\t\treturn this._backgroundColorFromAmbientLight;\n\t}\n\n\t/**\n\t * Sets if the canvas background color is derived from an {@link AmbientLight}.\n\t *\n\t * This only has effect when the canvas is not transparent. When not enabled, the background color\n\t * will be the canvas element's HTML/CSS background color.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset backgroundColorFromAmbientLight(backgroundColorFromAmbientLight) {\n\t\tthis._backgroundColorFromAmbientLight = backgroundColorFromAmbientLight !== false;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the canvas clear color.\n\t *\n\t * Default value is ````[1, 1, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget backgroundColor() {\n\t\treturn this._backgroundColor;\n\t}\n\n\t/**\n\t * Sets the canvas clear color.\n\t *\n\t * Default value is ````[1, 1, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset backgroundColor(value) {\n\t\tif (value) {\n\t\t\tthis._backgroundColor[0] = value[0];\n\t\t\tthis._backgroundColor[1] = value[1];\n\t\t\tthis._backgroundColor[2] = value[2];\n\t\t} else {\n\t\t\tthis._backgroundColor[0] = 1.0;\n\t\t\tthis._backgroundColor[1] = 1.0;\n\t\t\tthis._backgroundColor[2] = 1.0;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\n\t *\n\t * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\n\t * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\n\t * a performance boost.\n\t *\n\t * @returns {*|number} The resolution scale.\n\t */\n\tget resolutionScale() {\n\t\treturn this._resolutionScale;\n\t}\n\n\t/**\n\t * Sets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\n\t *\n\t * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\n\t * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\n\t * a performance boost.\n\t *\n\t * @param {*|number} resolutionScale The resolution scale.\n\t */\n\tset resolutionScale(resolutionScale) {\n\t\tresolutionScale = resolutionScale || 1.0;\n\t\tif (resolutionScale === this._resolutionScale) {\n\t\t\treturn;\n\t\t}\n\t\tthis._resolutionScale = resolutionScale;\n\t\tconst canvas = this.canvas;\n\t\tcanvas.width = Math.round(canvas.clientWidth * this._resolutionScale);\n\t\tcanvas.height = Math.round(canvas.clientHeight * this._resolutionScale);\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * The busy {@link Spinner} for this Canvas.\n\t *\n\t * @property spinner\n\t * @type Spinner\n\t * @final\n\t */\n\tget spinner() {\n\t\treturn this._spinner;\n\t}\n\n\t/**\n\t * Creates a default canvas in the DOM.\n\t * @private\n\t */\n\t_createCanvas() {\n\t\tconst canvasId = \"tctwins-canvas-\" + _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.createUUID();\n\t\tconst div = document.createElement(\"div\");\n\n\t\tconst style = div.style;\n\t\tstyle.height = \"100%\";\n\t\tstyle.width = \"100%\";\n\t\tstyle.padding = \"0\";\n\t\tstyle.margin = \"0\";\n\t\tstyle.background = \"rgba(0,0,0,0);\";\n\t\tstyle.float = \"left\";\n\t\tstyle.left = \"0\";\n\t\tstyle.top = \"0\";\n\t\tstyle.position = \"absolute\";\n\t\tstyle.opacity = \"1.0\";\n\t\tstyle[\"z-index\"] = \"-10000\";\n\n\t\tdiv.innerHTML +=\n\t\t\t'<canvas id=\"' + canvasId + '\" style=\"width: 100%; height: 100%; float: left; margin: 0; padding: 0;\"></canvas>';\n\n\t\tthis.parent.viewer.container.appendChild(div);\n\t\tthis.canvas = document.getElementById(canvasId);\n\t}\n\n\t_getElementXY(e) {\n\t\tlet x = 0,\n\t\t\ty = 0;\n\t\twhile (e) {\n\t\t\tx += e.offsetLeft - e.scrollLeft;\n\t\t\ty += e.offsetTop - e.scrollTop;\n\t\t\te = e.offsetParent;\n\t\t}\n\t\treturn { x: x, y: y };\n\t}\n\n\t/**\n\t * Initialises the WebGL context\n\t * @private\n\t */\n\t_initWebGL() {\n\t\t// Default context attribute values\n\n\t\tif (!this.gl) {\n\t\t\tfor (let i = 0; !this.gl && i < WEBGL_CONTEXT_NAMES.length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.gl = this.canvas.getContext(WEBGL_CONTEXT_NAMES[i], this.contextAttr);\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// Try with next context name\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!this.gl) {\n\t\t\tthis.error(\"Failed to get a WebGL context\");\n\n\t\t\t/**\n\t\t\t * Fired whenever the canvas failed to get a WebGL context, which probably means that WebGL\n\t\t\t * is either unsupported or has been disabled.\n\t\t\t * @event webglContextFailed\n\t\t\t */\n\t\t\tthis.fire(\"webglContextFailed\", true, true);\n\t\t}\n\n\t\t// data-textures: avoid to re-bind same texture\n\t\t{\n\t\t\tconst gl = this.gl;\n\n\t\t\tlet lastTextureUnit = \"__\";\n\n\t\t\tlet originalActiveTexture = gl.activeTexture;\n\n\t\t\tgl.activeTexture = function (arg1) {\n\t\t\t\tif (lastTextureUnit === arg1) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlastTextureUnit = arg1;\n\n\t\t\t\toriginalActiveTexture.call(this, arg1);\n\t\t\t};\n\n\t\t\tlet lastBindTexture = {};\n\n\t\t\tlet originalBindTexture = gl.bindTexture;\n\n\t\t\tlet avoidedRebinds = 0;\n\n\t\t\tgl.bindTexture = function (arg1, arg2) {\n\t\t\t\tif (lastBindTexture[lastTextureUnit] === arg2) {\n\t\t\t\t\tavoidedRebinds++;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlastBindTexture[lastTextureUnit] = arg2;\n\n\t\t\t\toriginalBindTexture.call(this, arg1, arg2);\n\t\t\t};\n\n\t\t\t// setInterval (\n\t\t\t// () => {\n\t\t\t// console.log (`${avoidedRebinds} avoided texture binds/sec`);\n\t\t\t// avoidedRebinds = 0;\n\t\t\t// },\n\t\t\t// 1000\n\t\t\t// );\n\t\t}\n\n\t\tif (this.gl) {\n\t\t\t// Setup extension (if necessary) and hints for fragment shader derivative functions\n\t\t\tif (this.webgl2) {\n\t\t\t\tthis.gl.hint(this.gl.FRAGMENT_SHADER_DERIVATIVE_HINT, this.gl.FASTEST);\n\n\t\t\t\t// data-textures: not using standard-derivatives\n\t\t\t\tif (!(this.gl instanceof WebGL2RenderingContext)) {\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @deprecated\n\t */\n\tgetSnapshot(params) {\n\t\tthrow \"Canvas#getSnapshot() has been replaced by Viewer#getSnapshot() - use that method instead.\";\n\t}\n\n\t/**\n\t * Reads colors of pixels from the last rendered frame.\n\t *\n\t * Call this method like this:\n\t *\n\t * ````JavaScript\n\t *\n\t * // Ignore transparent pixels (default is false)\n\t * var opaqueOnly = true;\n\t *\n\t * var colors = new Float32Array(8);\n\t *\n\t * viewer.scene.canvas.readPixels([ 100, 22, 12, 33 ], colors, 2, opaqueOnly);\n\t * ````\n\t *\n\t * Then the r,g,b components of the colors will be set to the colors at those pixels.\n\t *\n\t * @param {Number[]} pixels\n\t * @param {Number[]} colors\n\t * @param {Number} size\n\t * @param {Boolean} opaqueOnly\n\t */\n\treadPixels(pixels, colors, size, opaqueOnly) {\n\t\treturn this.scene._renderer.readPixels(pixels, colors, size, opaqueOnly);\n\t}\n\n\t/**\n\t * Simulates lost WebGL context.\n\t */\n\tloseWebGLContext() {\n\t\tif (this.canvas.loseContext) {\n\t\t\tthis.canvas.loseContext();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tthis.scene.off(this._tick);\n\t\tif (this._spinner) {\n\t\t\tthis._spinner.destroy();\n\t\t\tthis._spinner = null;\n\t\t}\n\t\t// Memory leak avoidance\n\t\tthis.canvas.removeEventListener(\"webglcontextlost\", this._webglcontextlostListener);\n\t\tthis.canvas.removeEventListener(\"webglcontextrestored\", this._webglcontextrestoredListener);\n\t\tif (this.gl != null) {\n\t\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);\n\t\t\tthis.gl = null;\n\t\t}\n\t\tsuper.destroy();\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/canvas/Canvas.js?");
|
|
2738
2738
|
|
|
2739
2739
|
/***/ }),
|
|
2740
2740
|
|
|
@@ -2744,7 +2744,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
2744
2744
|
\********************************************/
|
|
2745
2745
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2746
2746
|
|
|
2747
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Spinner: () => (/* binding */ Spinner)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n\r\n\r\nconst defaultCSS =\r\n\t\".sk-fading-circle {\\\r\n background: transparent;\\\r\n margin: 20px auto;\\\r\n width: 50px;\\\r\n height:50px;\\\r\n position: relative;\\\r\n }\\\r\n .sk-fading-circle .sk-circle {\\\r\n width: 120%;\\\r\n height: 120%;\\\r\n position: absolute;\\\r\n left: 0;\\\r\n top: 0;\\\r\n }\\\r\n .sk-fading-circle .sk-circle:before {\\\r\n content: '';\\\r\n display: block;\\\r\n margin: 0 auto;\\\r\n width: 15%;\\\r\n height: 15%;\\\r\n background-color: #66abdd;\\\r\n border-radius: 100%;\\\r\n -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\r\n animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\r\n }\\\r\n .sk-fading-circle .sk-circle2 {\\\r\n -webkit-transform: rotate(30deg);\\\r\n -ms-transform: rotate(30deg);\\\r\n transform: rotate(30deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle3 {\\\r\n -webkit-transform: rotate(60deg);\\\r\n -ms-transform: rotate(60deg);\\\r\n transform: rotate(60deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle4 {\\\r\n -webkit-transform: rotate(90deg);\\\r\n -ms-transform: rotate(90deg);\\\r\n transform: rotate(90deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle5 {\\\r\n -webkit-transform: rotate(120deg);\\\r\n -ms-transform: rotate(120deg);\\\r\n transform: rotate(120deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle6 {\\\r\n -webkit-transform: rotate(150deg);\\\r\n -ms-transform: rotate(150deg);\\\r\n transform: rotate(150deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle7 {\\\r\n -webkit-transform: rotate(180deg);\\\r\n -ms-transform: rotate(180deg);\\\r\n transform: rotate(180deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle8 {\\\r\n -webkit-transform: rotate(210deg);\\\r\n -ms-transform: rotate(210deg);\\\r\n transform: rotate(210deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle9 {\\\r\n -webkit-transform: rotate(240deg);\\\r\n -ms-transform: rotate(240deg);\\\r\n transform: rotate(240deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle10 {\\\r\n -webkit-transform: rotate(270deg);\\\r\n -ms-transform: rotate(270deg);\\\r\n transform: rotate(270deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle11 {\\\r\n -webkit-transform: rotate(300deg);\\\r\n -ms-transform: rotate(300deg);\\\r\n transform: rotate(300deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle12 {\\\r\n -webkit-transform: rotate(330deg);\\\r\n -ms-transform: rotate(330deg);\\\r\n transform: rotate(330deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle2:before {\\\r\n -webkit-animation-delay: -1.1s;\\\r\n animation-delay: -1.1s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle3:before {\\\r\n -webkit-animation-delay: -1s;\\\r\n animation-delay: -1s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle4:before {\\\r\n -webkit-animation-delay: -0.9s;\\\r\n animation-delay: -0.9s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle5:before {\\\r\n -webkit-animation-delay: -0.8s;\\\r\n animation-delay: -0.8s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle6:before {\\\r\n -webkit-animation-delay: -0.7s;\\\r\n animation-delay: -0.7s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle7:before {\\\r\n -webkit-animation-delay: -0.6s;\\\r\n animation-delay: -0.6s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle8:before {\\\r\n -webkit-animation-delay: -0.5s;\\\r\n animation-delay: -0.5s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle9:before {\\\r\n -webkit-animation-delay: -0.4s;\\\r\n animation-delay: -0.4s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle10:before {\\\r\n -webkit-animation-delay: -0.3s;\\\r\n animation-delay: -0.3s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle11:before {\\\r\n -webkit-animation-delay: -0.2s;\\\r\n animation-delay: -0.2s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle12:before {\\\r\n -webkit-animation-delay: -0.1s;\\\r\n animation-delay: -0.1s;\\\r\n }\\\r\n @-webkit-keyframes sk-circleFadeDelay {\\\r\n 0%, 39%, 100% { opacity: 0; }\\\r\n 40% { opacity: 1; }\\\r\n }\\\r\n @keyframes sk-circleFadeDelay {\\\r\n 0%, 39%, 100% { opacity: 0; }\\\r\n 40% { opacity: 1; }\\\r\n }\";\r\n\r\n/**\r\n * @desc Displays a progress animation at the center of its {@link Canvas} while things are loading or otherwise busy.\r\n *\r\n *\r\n * * Located at {@link Canvas#spinner}.\r\n * * Automatically shown while things are loading, however may also be shown by application code wanting to indicate busyness.\r\n * * {@link Spinner#processes} holds the count of active processes. As a process starts, it increments {@link Spinner#processes}, then decrements it on completion or failure.\r\n * * A Spinner is only visible while {@link Spinner#processes} is greater than zero.\r\n *\r\n * ````javascript\r\n * var spinner = viewer.scene.canvas.spinner;\r\n *\r\n * // Increment count of busy processes represented by the spinner;\r\n * // assuming the count was zero, this now shows the spinner\r\n * spinner.processes++;\r\n *\r\n * // Increment the count again, by some other process; spinner already visible, now requires two decrements\r\n * // before it becomes invisible again\r\n * spinner.processes++;\r\n *\r\n * // Decrement the count; count still greater than zero, so spinner remains visible\r\n * spinner.process--;\r\n *\r\n * // Decrement the count; count now zero, so spinner becomes invisible\r\n * spinner.process--;\r\n * ````\r\n */\r\nclass Spinner extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\t/**\r\n @private\r\n */\r\n\tget type() {\r\n\t\treturn \"Spinner\";\r\n\t}\r\n\r\n\t/**\r\n @private\r\n */\r\n\tconstructor(owner, cfg = {}) {\r\n\t\tsuper(owner, cfg);\r\n\r\n\t\tthis._canvas = cfg.canvas;\r\n\t\tthis._element = null;\r\n\t\tthis._isCustom = false; // True when the element is custom HTML\r\n\r\n\t\tif (cfg.elementId) {\r\n\t\t\t// Custom spinner element supplied\r\n\t\t\tthis._element = document.getElementById(cfg.elementId);\r\n\t\t\tif (!this._element) {\r\n\t\t\t\tthis._createDefaultSpinner(cfg.elementId);\r\n\t\t\t} else {\r\n\t\t\t\tthis._adjustPosition();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis._createDefaultSpinner(\"engine_spinner\");\r\n\t\t}\r\n\r\n\t\tthis._processes = 0;\r\n\t}\r\n\r\n\tget visible() {\r\n\t\treturn this._element.style[\"visibility\"] === \"visible\";\r\n\t}\r\n\r\n\tset visible(visible) {\r\n\t\tvisible ? (this._element.style[\"visibility\"] = \"visible\") : (this._element.style[\"visibility\"] = \"hidden\");\r\n\t}\r\n\r\n\t/** @private */\r\n\t_createDefaultSpinner(elementId) {\r\n\t\tconsole.log(\"_createDefaultSpinner\");\r\n\t\tthis._injectDefaultCSS();\r\n\t\tconst element = document.createElement(\"div\");\r\n\t\telement.setAttribute(\"id\", elementId);\r\n\t\tconst style = element.style;\r\n\t\tstyle[\"z-index\"] = \"9000\";\r\n\t\tstyle.position = \"absolute\";\r\n\t\telement.innerHTML =\r\n\t\t\t'<div class=\"sk-fading-circle\">\\\r\n <div class=\"sk-circle1 sk-circle\"></div>\\\r\n <div class=\"sk-circle2 sk-circle\"></div>\\\r\n <div class=\"sk-circle3 sk-circle\"></div>\\\r\n <div class=\"sk-circle4 sk-circle\"></div>\\\r\n <div class=\"sk-circle5 sk-circle\"></div>\\\r\n <div class=\"sk-circle6 sk-circle\"></div>\\\r\n <div class=\"sk-circle7 sk-circle\"></div>\\\r\n <div class=\"sk-circle8 sk-circle\"></div>\\\r\n <div class=\"sk-circle9 sk-circle\"></div>\\\r\n <div class=\"sk-circle10 sk-circle\"></div>\\\r\n <div class=\"sk-circle11 sk-circle\"></div>\\\r\n <div class=\"sk-circle12 sk-circle\"></div>\\\r\n </div>';\r\n\t\telement.setAttribute(\"class\", \"loading-circle\");\r\n\t\tif (this._canvas.parentElement) this._canvas.parentElement.appendChild(element);\r\n\t\telse {\r\n\t\t\tconst viewer = document.getElementById(\"myViewer\");\r\n\t\t\tviewer.appendChild(element);\r\n\t\t}\r\n\t\tthis._element = element;\r\n\t\tthis._isCustom = false;\r\n\t\tthis._adjustPosition();\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_injectDefaultCSS() {\r\n\t\tconst elementId = \"tctwins-spinner-css\";\r\n\t\tif (document.getElementById(elementId)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst defaultCSSNode = document.createElement(\"style\");\r\n\t\tdefaultCSSNode.innerHTML = defaultCSS;\r\n\t\tdefaultCSSNode.id = elementId;\r\n\t\tif (this._canvas.parentElement) this._canvas.parentElement.appendChild(defaultCSSNode);\r\n\t\telse {\r\n\t\t\tconst viewer = document.getElementById(\"myViewer\");\r\n\t\t\tviewer.appendChild(defaultCSSNode);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_adjustPosition() {\r\n\t\t// (Re)positions spinner DIV over the center of the canvas - called by Canvas\r\n\t\tif (this._isCustom) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst canvas = this._canvas;\r\n\t\tconst element = this._element;\r\n\t\tconst style = element.style;\r\n\t\tstyle[\"left\"] = canvas.offsetLeft + canvas.clientWidth * 0.5 - element.clientWidth * 0.5 + \"px\";\r\n\t\tstyle[\"top\"] = canvas.offsetTop + canvas.clientHeight * 0.5 - element.clientHeight * 0.5 + \"px\";\r\n\t}\r\n\r\n\t/**\r\n * Sets the number of processes this Spinner represents.\r\n *\r\n * The Spinner is visible while this property is greater than zero.\r\n *\r\n * Increment this property whenever you commence some process during which you want the Spinner to be visible, then decrement it again when the process is complete.\r\n *\r\n * Clamps to zero if you attempt to set to to a negative value.\r\n *\r\n * Fires a {@link Spinner#processes:event} event on change.\r\n\r\n * Default value is ````0````.\r\n *\r\n * @param {Number} value New processes count.\r\n */\r\n\tset processes(value) {\r\n\t\tvalue = value || 0;\r\n\t\tif (this._processes === value) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (value < 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst prevValue = this._processes;\r\n\t\tthis._processes = value;\r\n\t\tconst element = this._element;\r\n\t\tif (element) {\r\n\t\t\telement.style[\"visibility\"] = this._processes > 0 ? \"visible\" : \"hidden\";\r\n\t\t}\r\n\t\t/**\r\n Fired whenever this Spinner's {@link Spinner#visible} property changes.\r\n\r\n @event processes\r\n @param value The property's new value\r\n */\r\n\t\tthis.fire(\"processes\", this._processes);\r\n\t\tif (this._processes === 0 && this._processes !== prevValue) {\r\n\t\t\t/**\r\n Fired whenever this Spinner's {@link Spinner#visible} property becomes zero.\r\n\r\n @event zeroProcesses\r\n */\r\n\t\t\tthis.fire(\"zeroProcesses\", this._processes);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of processes this Spinner represents.\r\n\t *\r\n\t * The Spinner is visible while this property is greater than zero.\r\n\t *\r\n\t * @returns {Number} Current processes count.\r\n\t */\r\n\tget processes() {\r\n\t\treturn this._processes;\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tif (this._element && !this._isCustom) {\r\n\t\t\tthis._element.parentNode.removeChild(this._element);\r\n\t\t\tthis._element = null;\r\n\t\t}\r\n\t\tconst styleElement = document.getElementById(\"tctwins-spinner-css\");\r\n\t\tif (styleElement) {\r\n\t\t\tstyleElement.parentNode.removeChild(styleElement);\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/canvas/Spinner.js?");
|
|
2747
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Spinner: () => (/* binding */ Spinner)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n\r\n\r\nconst defaultCSS =\r\n\t\".sk-fading-circle {\\\r\n background: transparent;\\\r\n margin: 20px auto;\\\r\n width: 50px;\\\r\n height:50px;\\\r\n position: relative;\\\r\n }\\\r\n .sk-fading-circle .sk-circle {\\\r\n width: 120%;\\\r\n height: 120%;\\\r\n position: absolute;\\\r\n left: 0;\\\r\n top: 0;\\\r\n }\\\r\n .sk-fading-circle .sk-circle:before {\\\r\n content: '';\\\r\n display: block;\\\r\n margin: 0 auto;\\\r\n width: 15%;\\\r\n height: 15%;\\\r\n background-color: #66abdd;\\\r\n border-radius: 100%;\\\r\n -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\r\n animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\r\n }\\\r\n .sk-fading-circle .sk-circle2 {\\\r\n -webkit-transform: rotate(30deg);\\\r\n -ms-transform: rotate(30deg);\\\r\n transform: rotate(30deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle3 {\\\r\n -webkit-transform: rotate(60deg);\\\r\n -ms-transform: rotate(60deg);\\\r\n transform: rotate(60deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle4 {\\\r\n -webkit-transform: rotate(90deg);\\\r\n -ms-transform: rotate(90deg);\\\r\n transform: rotate(90deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle5 {\\\r\n -webkit-transform: rotate(120deg);\\\r\n -ms-transform: rotate(120deg);\\\r\n transform: rotate(120deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle6 {\\\r\n -webkit-transform: rotate(150deg);\\\r\n -ms-transform: rotate(150deg);\\\r\n transform: rotate(150deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle7 {\\\r\n -webkit-transform: rotate(180deg);\\\r\n -ms-transform: rotate(180deg);\\\r\n transform: rotate(180deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle8 {\\\r\n -webkit-transform: rotate(210deg);\\\r\n -ms-transform: rotate(210deg);\\\r\n transform: rotate(210deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle9 {\\\r\n -webkit-transform: rotate(240deg);\\\r\n -ms-transform: rotate(240deg);\\\r\n transform: rotate(240deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle10 {\\\r\n -webkit-transform: rotate(270deg);\\\r\n -ms-transform: rotate(270deg);\\\r\n transform: rotate(270deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle11 {\\\r\n -webkit-transform: rotate(300deg);\\\r\n -ms-transform: rotate(300deg);\\\r\n transform: rotate(300deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle12 {\\\r\n -webkit-transform: rotate(330deg);\\\r\n -ms-transform: rotate(330deg);\\\r\n transform: rotate(330deg);\\\r\n }\\\r\n .sk-fading-circle .sk-circle2:before {\\\r\n -webkit-animation-delay: -1.1s;\\\r\n animation-delay: -1.1s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle3:before {\\\r\n -webkit-animation-delay: -1s;\\\r\n animation-delay: -1s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle4:before {\\\r\n -webkit-animation-delay: -0.9s;\\\r\n animation-delay: -0.9s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle5:before {\\\r\n -webkit-animation-delay: -0.8s;\\\r\n animation-delay: -0.8s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle6:before {\\\r\n -webkit-animation-delay: -0.7s;\\\r\n animation-delay: -0.7s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle7:before {\\\r\n -webkit-animation-delay: -0.6s;\\\r\n animation-delay: -0.6s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle8:before {\\\r\n -webkit-animation-delay: -0.5s;\\\r\n animation-delay: -0.5s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle9:before {\\\r\n -webkit-animation-delay: -0.4s;\\\r\n animation-delay: -0.4s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle10:before {\\\r\n -webkit-animation-delay: -0.3s;\\\r\n animation-delay: -0.3s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle11:before {\\\r\n -webkit-animation-delay: -0.2s;\\\r\n animation-delay: -0.2s;\\\r\n }\\\r\n .sk-fading-circle .sk-circle12:before {\\\r\n -webkit-animation-delay: -0.1s;\\\r\n animation-delay: -0.1s;\\\r\n }\\\r\n @-webkit-keyframes sk-circleFadeDelay {\\\r\n 0%, 39%, 100% { opacity: 0; }\\\r\n 40% { opacity: 1; }\\\r\n }\\\r\n @keyframes sk-circleFadeDelay {\\\r\n 0%, 39%, 100% { opacity: 0; }\\\r\n 40% { opacity: 1; }\\\r\n }\";\r\n\r\n/**\r\n * @desc Displays a progress animation at the center of its {@link Canvas} while things are loading or otherwise busy.\r\n *\r\n *\r\n * * Located at {@link Canvas#spinner}.\r\n * * Automatically shown while things are loading, however may also be shown by application code wanting to indicate busyness.\r\n * * {@link Spinner#processes} holds the count of active processes. As a process starts, it increments {@link Spinner#processes}, then decrements it on completion or failure.\r\n * * A Spinner is only visible while {@link Spinner#processes} is greater than zero.\r\n *\r\n * ````javascript\r\n * var spinner = viewer.scene.canvas.spinner;\r\n *\r\n * // Increment count of busy processes represented by the spinner;\r\n * // assuming the count was zero, this now shows the spinner\r\n * spinner.processes++;\r\n *\r\n * // Increment the count again, by some other process; spinner already visible, now requires two decrements\r\n * // before it becomes invisible again\r\n * spinner.processes++;\r\n *\r\n * // Decrement the count; count still greater than zero, so spinner remains visible\r\n * spinner.process--;\r\n *\r\n * // Decrement the count; count now zero, so spinner becomes invisible\r\n * spinner.process--;\r\n * ````\r\n */\r\nclass Spinner extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\t/**\r\n @private\r\n */\r\n\tget type() {\r\n\t\treturn \"Spinner\";\r\n\t}\r\n\r\n\t/**\r\n @private\r\n */\r\n\tconstructor(owner, cfg = {}) {\r\n\t\tsuper(owner, cfg);\r\n\r\n\t\tthis._canvas = cfg.canvas;\r\n\t\tthis._element = null;\r\n\t\tthis._isCustom = false; // True when the element is custom HTML\r\n\r\n\t\tif (cfg.elementId) {\r\n\t\t\t// Custom spinner element supplied\r\n\t\t\tthis._element = document.getElementById(cfg.elementId);\r\n\t\t\tif (!this._element) {\r\n\t\t\t\tthis._createDefaultSpinner(cfg.elementId);\r\n\t\t\t} else {\r\n\t\t\t\tthis._adjustPosition();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis._createDefaultSpinner(\"engine_spinner\");\r\n\t\t}\r\n\r\n\t\tthis.processes = 0;\r\n\t}\r\n\r\n\tget visible() {\r\n\t\treturn this._element.style[\"visibility\"] === \"visible\";\r\n\t}\r\n\r\n\tset visible(visible) {\r\n\t\tvisible ? (this._element.style[\"visibility\"] = \"visible\") : (this._element.style[\"visibility\"] = \"hidden\");\r\n\t}\r\n\r\n\t/** @private */\r\n\t_createDefaultSpinner(elementId) {\r\n\t\tconsole.log(\"_createDefaultSpinner\");\r\n\t\tthis._injectDefaultCSS();\r\n\t\tconst element = document.createElement(\"div\");\r\n\t\telement.setAttribute(\"id\", elementId);\r\n\t\tconst style = element.style;\r\n\t\tstyle[\"z-index\"] = \"9000\";\r\n\t\tstyle.position = \"absolute\";\r\n\t\telement.innerHTML =\r\n\t\t\t'<div class=\"sk-fading-circle\">\\\r\n <div class=\"sk-circle1 sk-circle\"></div>\\\r\n <div class=\"sk-circle2 sk-circle\"></div>\\\r\n <div class=\"sk-circle3 sk-circle\"></div>\\\r\n <div class=\"sk-circle4 sk-circle\"></div>\\\r\n <div class=\"sk-circle5 sk-circle\"></div>\\\r\n <div class=\"sk-circle6 sk-circle\"></div>\\\r\n <div class=\"sk-circle7 sk-circle\"></div>\\\r\n <div class=\"sk-circle8 sk-circle\"></div>\\\r\n <div class=\"sk-circle9 sk-circle\"></div>\\\r\n <div class=\"sk-circle10 sk-circle\"></div>\\\r\n <div class=\"sk-circle11 sk-circle\"></div>\\\r\n <div class=\"sk-circle12 sk-circle\"></div>\\\r\n </div>';\r\n\t\telement.setAttribute(\"class\", \"loading-circle\");\r\n\t\tif (this._canvas.parentElement) this._canvas.parentElement.appendChild(element);\r\n\t\telse {\r\n\t\t\tconst viewer = document.getElementById(\"myViewer\");\r\n\t\t\tviewer.appendChild(element);\r\n\t\t}\r\n\t\tthis._element = element;\r\n\t\tthis._isCustom = false;\r\n\t\tthis._adjustPosition();\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_injectDefaultCSS() {\r\n\t\tconst elementId = \"tctwins-spinner-css\";\r\n\t\tif (document.getElementById(elementId)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst defaultCSSNode = document.createElement(\"style\");\r\n\t\tdefaultCSSNode.innerHTML = defaultCSS;\r\n\t\tdefaultCSSNode.id = elementId;\r\n\t\tif (this._canvas.parentElement) this._canvas.parentElement.appendChild(defaultCSSNode);\r\n\t\telse {\r\n\t\t\tconst viewer = document.getElementById(\"myViewer\");\r\n\t\t\tviewer.appendChild(defaultCSSNode);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_adjustPosition() {\r\n\t\t// (Re)positions spinner DIV over the center of the canvas - called by Canvas\r\n\t\tif (this._isCustom) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst canvas = this._canvas;\r\n\t\tconst element = this._element;\r\n\t\tconst style = element.style;\r\n\t\tstyle[\"left\"] = canvas.offsetLeft + canvas.clientWidth * 0.5 - element.clientWidth * 0.5 + \"px\";\r\n\t\tstyle[\"top\"] = canvas.offsetTop + canvas.clientHeight * 0.5 - element.clientHeight * 0.5 + \"px\";\r\n\t}\r\n\r\n\t/**\r\n * Sets the number of processes this Spinner represents.\r\n *\r\n * The Spinner is visible while this property is greater than zero.\r\n *\r\n * Increment this property whenever you commence some process during which you want the Spinner to be visible, then decrement it again when the process is complete.\r\n *\r\n * Clamps to zero if you attempt to set to to a negative value.\r\n *\r\n * Fires a {@link Spinner#processes:event} event on change.\r\n\r\n * Default value is ````0````.\r\n *\r\n * @param {Number} value New processes count.\r\n */\r\n\tset processes(value) {\r\n\t\tvalue = value || 0;\r\n\t\tif (this._processes === value) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (value < 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst prevValue = this._processes;\r\n\t\tthis._processes = value;\r\n\t\tconst element = this._element;\r\n\t\tif (element) {\r\n\t\t\telement.style[\"visibility\"] = this._processes > 0 ? \"visible\" : \"hidden\";\r\n\t\t}\r\n\t\t/**\r\n Fired whenever this Spinner's {@link Spinner#visible} property changes.\r\n\r\n @event processes\r\n @param value The property's new value\r\n */\r\n\t\tthis.fire(\"processes\", this._processes);\r\n\t\tif (this._processes === 0 && this._processes !== prevValue) {\r\n\t\t\t/**\r\n Fired whenever this Spinner's {@link Spinner#visible} property becomes zero.\r\n\r\n @event zeroProcesses\r\n */\r\n\t\t\tthis.fire(\"zeroProcesses\", this._processes);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of processes this Spinner represents.\r\n\t *\r\n\t * The Spinner is visible while this property is greater than zero.\r\n\t *\r\n\t * @returns {Number} Current processes count.\r\n\t */\r\n\tget processes() {\r\n\t\treturn this._processes;\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tif (this._element && !this._isCustom) {\r\n\t\t\tthis._element.parentNode.removeChild(this._element);\r\n\t\t\tthis._element = null;\r\n\t\t}\r\n\t\tconst styleElement = document.getElementById(\"tctwins-spinner-css\");\r\n\t\tif (styleElement) {\r\n\t\t\tstyleElement.parentNode.removeChild(styleElement);\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/canvas/Spinner.js?");
|
|
2748
2748
|
|
|
2749
2749
|
/***/ }),
|
|
2750
2750
|
|
|
@@ -4804,7 +4804,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
|
|
4804
4804
|
\*****************************************/
|
|
4805
4805
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
4806
4806
|
|
|
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\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// Enables runtime check for redundant calls to object state update methods, eg. Scene#_objectVisibilityUpdated\r\nconst ASSERT_OBJECT_STATE_UPDATE = false;\r\n\r\n// Cached vars to avoid garbage collection\r\n\r\nfunction getEntityIDMap(scene, entityIds) {\r\n\tconst map = {};\r\n\tlet entityId;\r\n\tlet entity;\r\n\tfor (let i = 0, len = entityIds.length; i < len; i++) {\r\n\t\tentityId = entityIds[i];\r\n\t\tentity = scene.components[entityId];\r\n\t\tif (!entity) {\r\n\t\t\tscene.warn(\"pick(): Component not found: \" + entityId);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (!entity.isEntity) {\r\n\t\t\tscene.warn(\"pick(): Component is not an Entity: \" + entityId);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tmap[entityId] = true;\r\n\t}\r\n\treturn map;\r\n}\r\n\r\n/**\r\n * Fired whenever a debug message is logged on a component within this Scene.\r\n * @event log\r\n * @param {String} value The debug message\r\n */\r\n\r\n/**\r\n * Fired whenever an error is logged on a component within this Scene.\r\n * @event error\r\n * @param {String} value The error message\r\n */\r\n\r\n/**\r\n * Fired whenever a warning is logged on a component within this Scene.\r\n * @event warn\r\n * @param {String} value The warning message\r\n */\r\n\r\n/**\r\n * @desc Contains the components that comprise a 3D scene.\r\n *\r\n * * A {@link Viewer} has a single Scene, which it provides in {@link Viewer#scene}.\r\n * * Plugins like {@link AxisGizmoPlugin} also have their own private Scenes.\r\n * * Each Scene has a corresponding {@link MetaScene}, which the Viewer provides in {@link Viewer#metaScene}.\r\n *\r\n * ## Getting a Viewer's Scene\r\n *\r\n * ````javascript\r\n * var scene = viewer.scene;\r\n * ````\r\n *\r\n * ## Creating and accessing Scene components\r\n *\r\n * As a brief introduction to creating Scene components, we'll create a {@link Mesh} that has a\r\n * {@link buildTorusGeometry} and a {@link PhongMaterial}:\r\n *\r\n * ````javascript\r\n * var teapotMesh = new Mesh(scene, {\r\n * id: \"myMesh\", // <<---------- ID automatically generated if not provided\r\n * geometry: new TorusGeometry(scene),\r\n * material: new PhongMaterial(scene, {\r\n * id: \"myMaterial\",\r\n * diffuse: [0.2, 0.2, 1.0]\r\n * })\r\n * });\r\n *\r\n * teapotMesh.scene.camera.eye = [45, 45, 45];\r\n * ````\r\n *\r\n * Find components by ID in their Scene's {@link Scene#components} map:\r\n *\r\n * ````javascript\r\n * var teapotMesh = scene.components[\"myMesh\"];\r\n * teapotMesh.visible = false;\r\n *\r\n * var teapotMaterial = scene.components[\"myMaterial\"];\r\n * teapotMaterial.diffuse = [1,0,0]; // Change to red\r\n * ````\r\n *\r\n * A Scene also has a map of component instances for each {@link Component} subtype:\r\n *\r\n * ````javascript\r\n * var meshes = scene.types[\"Mesh\"];\r\n * var teapotMesh = meshes[\"myMesh\"];\r\n * teapotMesh.xrayed = true;\r\n *\r\n * var phongMaterials = scene.types[\"PhongMaterial\"];\r\n * var teapotMaterial = phongMaterials[\"myMaterial\"];\r\n * teapotMaterial.diffuse = [0,1,0]; // Change to green\r\n * ````\r\n *\r\n * See {@link Node}, {@link Node} and {@link Model} for how to create and access more sophisticated content.\r\n *\r\n * ## Controlling the camera\r\n *\r\n * Use the Scene's {@link Camera} to control the current viewpoint and projection:\r\n *\r\n * ````javascript\r\n * var camera = myScene.camera;\r\n *\r\n * camera.eye = [-10,0,0];\r\n * camera.look = [-10,0,0];\r\n * camera.up = [0,1,0];\r\n *\r\n * camera.projection = \"perspective\";\r\n * camera.perspective.fov = 45;\r\n * //...\r\n * ````\r\n *\r\n * ## Managing the canvas\r\n *\r\n * The Scene's {@link Canvas} component provides various conveniences relevant to the WebGL canvas, such\r\n * as firing resize events etc:\r\n *\r\n * ````javascript\r\n * var canvas = scene.canvas;\r\n *\r\n * canvas.on(\"boundary\", function(boundary) {\r\n * //...\r\n * });\r\n * ````\r\n *\r\n * ## Picking\r\n *\r\n * Use {@link Scene#pick} to pick and raycast entites.\r\n *\r\n * For example, to pick a point on the surface of the closest entity at the given canvas coordinates:\r\n *\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * pickSurface: true,\r\n * canvasPos: [23, 131]\r\n * });\r\n *\r\n * if (pickResult) { // Picked an entity\r\n *\r\n * var entity = pickResult.entity;\r\n *\r\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\r\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Mesh's Geometry's indices array\r\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\r\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\r\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\r\n * var viewPos = pickResult. ; // Float64Array containing the picked View-space position on the triangle\r\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\r\n * var normal = pickResult.normal; // Float64Array containing the interpolated normal vector at the picked position on the triangle\r\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\r\n * }\r\n * ````\r\n *\r\n * ## Pick masking\r\n *\r\n * We can use {@link Scene#pick}'s ````includeEntities```` and ````excludeEntities```` options to mask which {@link Mesh}es we attempt to pick.\r\n *\r\n * This is useful for picking through things, to pick only the Entities of interest.\r\n *\r\n * To pick only Entities ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through any other Entities that are\r\n * in the way, as if they weren't there:\r\n *\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * canvasPos: [23, 131],\r\n * includeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\r\n * });\r\n *\r\n * if (pickResult) {\r\n * // Entity will always be either \"gearbox#77.0\" or \"gearbox#79.0\"\r\n * var entity = pickResult.entity;\r\n * }\r\n * ````\r\n *\r\n * To pick any pickable Entity, except for ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through those\r\n * Entities if they happen to be in the way:\r\n *\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * canvasPos: [23, 131],\r\n * excludeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\r\n * });\r\n *\r\n * if (pickResult) {\r\n * // Entity will never be \"gearbox#77.0\" or \"gearbox#79.0\"\r\n * var entity = pickResult.entity;\r\n * }\r\n * ````\r\n *\r\n * See {@link Scene#pick} for more info on picking.\r\n *\r\n * ## Querying and tracking boundaries\r\n *\r\n * Getting a Scene's World-space axis-aligned boundary (AABB):\r\n *\r\n * ````javascript\r\n * var aabb = scene.aabb; // [xmin, ymin, zmin, xmax, ymax, zmax]\r\n * ````\r\n *\r\n * Subscribing to updates to the AABB, which occur whenever {@link Entity}s are transformed, their\r\n * {@link ReadableGeometry}s have been updated, or the {@link Camera} has moved:\r\n *\r\n * ````javascript\r\n * scene.on(\"boundary\", function() {\r\n * var aabb = scene.aabb;\r\n * });\r\n * ````\r\n *\r\n * Getting the AABB of the {@link Entity}s with the given IDs:\r\n *\r\n * ````JavaScript\r\n * scene.getAABB(); // Gets collective boundary of all Entities in the scene\r\n * scene.getAABB(\"saw\"); // Gets boundary of an Object\r\n * scene.getAABB([\"saw\", \"gearbox\"]); // Gets collective boundary of two Objects\r\n * ````\r\n *\r\n * See {@link Scene#getAABB} and {@link Entity} for more info on querying and tracking boundaries.\r\n *\r\n * ## Managing the viewport\r\n *\r\n * The Scene's {@link Viewport} component manages the WebGL viewport:\r\n *\r\n * ````javascript\r\n * var viewport = scene.viewport\r\n * viewport.boundary = [0, 0, 500, 400];;\r\n * ````\r\n *\r\n * ## Controlling rendering\r\n *\r\n * You can configure a Scene to perform multiple \"passes\" (renders) per frame. This is useful when we want to render the\r\n * scene to multiple viewports, such as for stereo effects.\r\n *\r\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\r\n * with a callback that intercepts the Scene before each render and sets its {@link Viewport} to a\r\n * different portion of the canvas. By default, the Scene will clear the canvas only before the first render, allowing the\r\n * two views to be shown on the canvas at the same time.\r\n *\r\n * ````Javascript\r\n * var viewport = scene.viewport;\r\n *\r\n * // Configure Scene to render twice for each frame\r\n * scene.passes = 2; // Default is 1\r\n * scene.clearEachPass = false; // Default is false\r\n *\r\n * // Render to a separate viewport on each render\r\n *\r\n * var viewport = scene.viewport;\r\n * viewport.autoBoundary = false;\r\n *\r\n * scene.on(\"rendering\", function (e) {\r\n * switch (e.pass) {\r\n * case 0:\r\n * viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height\r\n * break;\r\n *\r\n * case 1:\r\n * viewport.boundary = [200, 0, 200, 200];\r\n * break;\r\n * }\r\n * });\r\n *\r\n * // We can also intercept the Scene after each render,\r\n * // (though we're not using this for anything here)\r\n * scene.on(\"rendered\", function (e) {\r\n * switch (e.pass) {\r\n * case 0:\r\n * break;\r\n *\r\n * case 1:\r\n * break;\r\n * }\r\n * });\r\n * ````\r\n *\r\n * ## Gamma correction\r\n *\r\n * Within its shaders, xeokit performs shading calculations in linear space.\r\n *\r\n * By default, the Scene expects color textures (eg. {@link PhongMaterial#diffuseMap},\r\n * {@link MetallicMaterial#baseColorMap} and {@link SpecularMaterial#diffuseMap}) to\r\n * be in pre-multipled gamma space, so will convert those to linear space before they are used in shaders. Other textures are\r\n * always expected to be in linear space.\r\n *\r\n * By default, the Scene will also gamma-correct its rendered output.\r\n *\r\n * You can configure the Scene to expect all those color textures to be linear space, so that it does not gamma-correct them:\r\n *\r\n * ````javascript\r\n * scene.gammaInput = false;\r\n * ````\r\n *\r\n * You would still need to gamma-correct the output, though, if it's going straight to the canvas, so normally we would\r\n * leave that enabled:\r\n *\r\n * ````javascript\r\n * scene.gammaOutput = true;\r\n * ````\r\n *\r\n * See {@link Texture} for more information on texture encoding and gamma.\r\n *\r\n * @class Scene\r\n */\r\nclass Scene extends _Component_js__WEBPACK_IMPORTED_MODULE_4__.Component {\r\n\t/**\r\n @private\r\n */\r\n\tget type() {\r\n\t\treturn \"Scene\";\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The Viewer this Scene belongs to.\r\n\t * @param {Object} cfg Scene configuration.\r\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.\r\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.\r\n\t * @param {HTMLElement} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\r\n\t * @param {number} [cfg.numCachedSectionPlanes=0] Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity\r\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\r\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\r\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\r\n\t * your expected usage.\r\n\t * @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(null, cfg);\r\n\r\n\t\tconst canvas = cfg.canvasElement || document.getElementById(cfg.canvasId);\r\n\r\n\t\tif (!(canvas instanceof HTMLCanvasElement)) {\r\n\t\t\tthrow \"Mandatory config expected: valid canvasId or canvasElement\";\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}\r\n\t\t */\r\n\t\tthis._tickifiedFunctions = {};\r\n\r\n\t\tthis._transparent = !!cfg.transparent;\r\n\t\tconst alphaDepthMask = !!cfg.alphaDepthMask;\r\n\t\tthis._edgesEnabled = !!cfg.edgesEnabled;\r\n\r\n\t\tthis._aabbDirty = true;\r\n\r\n\t\t/**\r\n\t\t * The {@link Viewer} this Scene belongs to.\r\n\t\t * @type {Viewer}\r\n\t\t */\r\n\t\tthis.viewer = viewer;\r\n\r\n\t\t/** Decremented each frame, triggers occlusion test for occludable {@link Marker}s when zero.\r\n\t\t * @private\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\tthis.occlusionTestCountdown = 0;\r\n\r\n\t\t/**\r\n The number of models currently loading.\r\n\r\n @property loading\r\n @final\r\n @type {Number}\r\n */\r\n\t\tthis.loading = 0;\r\n\r\n\t\t/**\r\n The epoch time (in milliseconds since 1970) when this Scene was instantiated.\r\n\r\n @property timeCreated\r\n @final\r\n @type {Number}\r\n */\r\n\t\tthis.startTime = new Date().getTime();\r\n\r\n\t\t/**\r\n\t\t * Map of {@link Entity}s that represent models.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isModel} is ````true````.\r\n\t\t *\r\n\t\t * @property models\r\n\t\t * @final\r\n\t\t * @type {{String:Entity}}\r\n\t\t */\r\n\t\tthis.models = {};\r\n\r\n\t\t/**\r\n\t\t * Map of {@link Entity}s that represents objects.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isObject} is ````true````.\r\n\t\t *\r\n\t\t * @property objects\r\n\t\t * @final\r\n\t\t * @type {{String:Entity}}\r\n\t\t */\r\n\t\tthis.objects = {};\r\n\t\tthis._numObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of currently visible {@link Entity}s that represent objects.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is visible when {@link Entity#visible} is true.\r\n\t\t *\r\n\t\t * @property visibleObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.visibleObjects = {};\r\n\t\tthis._numVisibleObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of currently xrayed {@link Entity}s that represent objects.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is xrayed when {@link Entity#xrayed} is true.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property xrayedObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.xrayedObjects = {};\r\n\t\tthis._numXRayedObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of currently highlighted {@link Entity}s that represent objects.\r\n\t\t *\r\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.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property highlightedObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.highlightedObjects = {};\r\n\t\tthis._numHighlightedObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of currently selected {@link Entity}s that represent objects.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is true, and is selected while {@link Entity#selected} is true.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property selectedObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.selectedObjects = {};\r\n\t\tthis._numSelectedObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of currently colorized {@link Entity}s that represent objects.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property colorizedObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.colorizedObjects = {};\r\n\t\tthis._numColorizedObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of {@link Entity}s that represent objects whose opacity was updated.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property opacityObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.opacityObjects = {};\r\n\t\tthis._numOpacityObjects = 0;\r\n\r\n\t\t/**\r\n\t\t * Map of {@link Entity}s that represent objects whose {@link Entity#offset}s were updated.\r\n\t\t *\r\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\r\n\t\t *\r\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\r\n\t\t *\r\n\t\t * @property offsetObjects\r\n\t\t * @final\r\n\t\t * @type {{String:Object}}\r\n\t\t */\r\n\t\tthis.offsetObjects = {};\r\n\t\tthis._numOffsetObjects = 0;\r\n\r\n\t\t// Cached ID arrays, lazy-rebuilt as needed when stale after map updates\r\n\r\n\t\t/**\r\n Lazy-regenerated ID lists.\r\n */\r\n\t\tthis._modelIds = null;\r\n\t\tthis._objectIds = null;\r\n\t\tthis._visibleObjectIds = null;\r\n\t\tthis._xrayedObjectIds = null;\r\n\t\tthis._highlightedObjectIds = null;\r\n\t\tthis._selectedObjectIds = null;\r\n\t\tthis._colorizedObjectIds = null;\r\n\t\tthis._opacityObjectIds = null;\r\n\t\tthis._offsetObjectIds = null;\r\n\r\n\t\tthis._collidables = {}; // Components that contribute to the Scene AABB\r\n\t\tthis._compilables = {}; // Components that require shader compilation\r\n\r\n\t\tthis._needRecompile = false;\r\n\r\n\t\t/**\r\n\t\t * For each {@link Component} type, a map of IDs to {@link Component} instances of that type.\r\n\t\t *\r\n\t\t * @type {{String:{String:Component}}}\r\n\t\t */\r\n\t\tthis.types = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link Component}s within this Scene, each mapped to its {@link Component#id}.\r\n\t\t *\r\n\t\t * *@type {{String:Component}}\r\n\t\t */\r\n\t\tthis.components = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link SectionPlane}s in this Scene, each mapped to its {@link SectionPlane#id}.\r\n\t\t *\r\n\t\t * @type {{String:SectionPlane}}\r\n\t\t */\r\n\t\tthis.sectionPlanes = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link Light}s in this Scene, each mapped to its {@link Light#id}.\r\n\t\t *\r\n\t\t * @type {{String:Light}}\r\n\t\t */\r\n\t\tthis.lights = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link LightMap}s in this Scene, each mapped to its {@link LightMap#id}.\r\n\t\t *\r\n\t\t * @type {{String:LightMap}}\r\n\t\t */\r\n\t\tthis.lightMaps = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link ReflectionMap}s in this Scene, each mapped to its {@link ReflectionMap#id}.\r\n\t\t *\r\n\t\t * @type {{String:ReflectionMap}}\r\n\t\t */\r\n\t\tthis.reflectionMaps = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link Bitmap}s in this Scene, each mapped to its {@link Bitmap#id}.\r\n\t\t *\r\n\t\t * @type {{String:Bitmap}}\r\n\t\t */\r\n\t\tthis.bitmaps = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link LineSet}s in this Scene, each mapped to its {@link LineSet#id}.\r\n\t\t *\r\n\t\t * @type {{String:LineSet}}\r\n\t\t */\r\n\t\tthis.lineSets = {};\r\n\r\n\t\t/**\r\n\t\t * The real world offset for this Scene\r\n\t\t *\r\n\t\t * @type {Number[]}\r\n\t\t */\r\n\t\tthis.realWorldOffset = cfg.realWorldOffset || new Float64Array([0, 0, 0]);\r\n\r\n\t\t/**\r\n\t\t * Manages the HTML5 canvas for this Scene.\r\n\t\t *\r\n\t\t * @type {Canvas}\r\n\t\t */\r\n\t\tthis.canvas = new _canvas_Canvas_js__WEBPACK_IMPORTED_MODULE_5__.Canvas(this, {\r\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\r\n\t\t\tcanvas: canvas,\r\n\t\t\tspinnerElementId: cfg.spinnerElementId,\r\n\t\t\ttransparent: this._transparent,\r\n\t\t\twebgl2: cfg.webgl2 !== false,\r\n\t\t\tcontextAttr: cfg.contextAttr || {},\r\n\t\t\tbackgroundColor: cfg.backgroundColor,\r\n\t\t\tbackgroundColorFromAmbientLight: cfg.backgroundColorFromAmbientLight,\r\n\t\t\tpremultipliedAlpha: cfg.premultipliedAlpha\r\n\t\t});\r\n\r\n\t\tthis.canvas.on(\"boundary\", () => {\r\n\t\t\tthis.glRedraw();\r\n\t\t});\r\n\r\n\t\tthis.canvas.on(\"webglContextFailed\", () => {\r\n\t\t\talert(\"xeokit failed to find WebGL!\");\r\n\t\t});\r\n\r\n\t\tthis._renderer = new _webgl_Renderer_js__WEBPACK_IMPORTED_MODULE_6__.Renderer(this, {\r\n\t\t\ttransparent: this._transparent,\r\n\t\t\talphaDepthMask: alphaDepthMask,\r\n\t\t\tedgesEnabled: this._edgesEnabled\r\n\t\t});\r\n\r\n\t\tthis._sectionPlanesState = new (function () {\r\n\t\t\tthis.sectionPlanes = [];\r\n\r\n\t\t\tthis.clippingCaps = false;\r\n\r\n\t\t\tthis._numCachedSectionPlanes = 0;\r\n\r\n\t\t\tlet hash = null;\r\n\r\n\t\t\tthis.getHash = function () {\r\n\t\t\t\tif (hash) {\r\n\t\t\t\t\treturn hash;\r\n\t\t\t\t}\r\n\t\t\t\tconst numAllocatedSectionPlanes = this.getNumAllocatedSectionPlanes();\r\n\t\t\t\tconst sectionPlanes = this.sectionPlanes;\r\n\t\t\t\tif (numAllocatedSectionPlanes === 0) {\r\n\t\t\t\t\treturn (this.hash = \";\");\r\n\t\t\t\t}\r\n\t\t\t\tlet sectionPlane;\r\n\r\n\t\t\t\tconst hashParts = [];\r\n\t\t\t\tfor (let i = 0, len = numAllocatedSectionPlanes; i < len; i++) {\r\n\t\t\t\t\tsectionPlane = sectionPlanes[i];\r\n\t\t\t\t\thashParts.push(\"cp\");\r\n\t\t\t\t}\r\n\t\t\t\thashParts.push(\";\");\r\n\t\t\t\thash = hashParts.join(\"\");\r\n\t\t\t\treturn hash;\r\n\t\t\t};\r\n\r\n\t\t\tthis.addSectionPlane = function (sectionPlane) {\r\n\t\t\t\tthis.sectionPlanes.push(sectionPlane);\r\n\t\t\t\thash = null;\r\n\t\t\t};\r\n\r\n\t\t\tthis.removeSectionPlane = function (sectionPlane) {\r\n\t\t\t\tfor (let i = 0, len = this.sectionPlanes.length; i < len; i++) {\r\n\t\t\t\t\tif (this.sectionPlanes[i].id === sectionPlane.id) {\r\n\t\t\t\t\t\tthis.sectionPlanes.splice(i, 1);\r\n\t\t\t\t\t\thash = null;\r\n\t\t\t\t\t\treturn;\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.setNumCachedSectionPlanes = function (numCachedSectionPlanes) {\r\n\t\t\t\tthis._numCachedSectionPlanes = numCachedSectionPlanes;\r\n\t\t\t\thash = null;\r\n\t\t\t};\r\n\r\n\t\t\tthis.getNumCachedSectionPlanes = function () {\r\n\t\t\t\treturn this._numCachedSectionPlanes;\r\n\t\t\t};\r\n\r\n\t\t\tthis.getNumAllocatedSectionPlanes = function () {\r\n\t\t\t\tconst num = this.sectionPlanes.length;\r\n\t\t\t\treturn num > this._numCachedSectionPlanes ? num : this._numCachedSectionPlanes;\r\n\t\t\t};\r\n\t\t})();\r\n\r\n\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(cfg.numCachedSectionPlanes || 0);\r\n\r\n\t\tthis._lightsState = new (function () {\r\n\t\t\tconst DEFAULT_AMBIENT = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 0]);\r\n\t\t\tconst ambientColorIntensity = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4();\r\n\r\n\t\t\tthis.lights = [];\r\n\t\t\tthis.reflectionMaps = [];\r\n\t\t\tthis.lightMaps = [];\r\n\r\n\t\t\tlet hash = null;\r\n\t\t\tlet ambientLight = null;\r\n\r\n\t\t\tthis.getHash = function () {\r\n\t\t\t\tif (hash) {\r\n\t\t\t\t\treturn hash;\r\n\t\t\t\t}\r\n\t\t\t\tconst hashParts = [];\r\n\t\t\t\tconst lights = this.lights;\r\n\t\t\t\tlet light;\r\n\t\t\t\tfor (let i = 0, len = lights.length; i < len; i++) {\r\n\t\t\t\t\tlight = lights[i];\r\n\t\t\t\t\thashParts.push(\"/\");\r\n\t\t\t\t\thashParts.push(light.type);\r\n\t\t\t\t\thashParts.push(light.space === \"world\" ? \"w\" : \"v\");\r\n\t\t\t\t\tif (light.castsShadow) {\r\n\t\t\t\t\t\thashParts.push(\"sh\");\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (this.lightMaps.length > 0) {\r\n\t\t\t\t\thashParts.push(\"/lm\");\r\n\t\t\t\t}\r\n\t\t\t\tif (this.reflectionMaps.length > 0) {\r\n\t\t\t\t\thashParts.push(\"/rm\");\r\n\t\t\t\t}\r\n\t\t\t\thashParts.push(\";\");\r\n\t\t\t\thash = hashParts.join(\"\");\r\n\t\t\t\treturn hash;\r\n\t\t\t};\r\n\r\n\t\t\tthis.addLight = function (state) {\r\n\t\t\t\tthis.lights.push(state);\r\n\t\t\t\tambientLight = null;\r\n\t\t\t\thash = null;\r\n\t\t\t};\r\n\r\n\t\t\tthis.removeLight = function (state) {\r\n\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\r\n\t\t\t\t\tconst light = this.lights[i];\r\n\t\t\t\t\tif (light.id === state.id) {\r\n\t\t\t\t\t\tthis.lights.splice(i, 1);\r\n\t\t\t\t\t\tif (ambientLight && ambientLight.id === state.id) {\r\n\t\t\t\t\t\t\tambientLight = null;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\thash = null;\r\n\t\t\t\t\t\treturn;\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.addReflectionMap = function (state) {\r\n\t\t\t\tthis.reflectionMaps.push(state);\r\n\t\t\t\thash = null;\r\n\t\t\t};\r\n\r\n\t\t\tthis.removeReflectionMap = function (state) {\r\n\t\t\t\tfor (let i = 0, len = this.reflectionMaps.length; i < len; i++) {\r\n\t\t\t\t\tif (this.reflectionMaps[i].id === state.id) {\r\n\t\t\t\t\t\tthis.reflectionMaps.splice(i, 1);\r\n\t\t\t\t\t\thash = null;\r\n\t\t\t\t\t\treturn;\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.addLightMap = function (state) {\r\n\t\t\t\tthis.lightMaps.push(state);\r\n\t\t\t\thash = null;\r\n\t\t\t};\r\n\r\n\t\t\tthis.removeLightMap = function (state) {\r\n\t\t\t\tfor (let i = 0, len = this.lightMaps.length; i < len; i++) {\r\n\t\t\t\t\tif (this.lightMaps[i].id === state.id) {\r\n\t\t\t\t\t\tthis.lightMaps.splice(i, 1);\r\n\t\t\t\t\t\thash = null;\r\n\t\t\t\t\t\treturn;\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.getAmbientColorAndIntensity = function () {\r\n\t\t\t\tif (!ambientLight) {\r\n\t\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\r\n\t\t\t\t\t\tconst light = this.lights[i];\r\n\t\t\t\t\t\tif (light.type === \"ambient\") {\r\n\t\t\t\t\t\t\tambientLight = light;\r\n\t\t\t\t\t\t\tbreak;\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\tif (ambientLight) {\r\n\t\t\t\t\tconst color = ambientLight.color;\r\n\t\t\t\t\tconst intensity = ambientLight.intensity;\r\n\t\t\t\t\tambientColorIntensity[0] = color[0];\r\n\t\t\t\t\tambientColorIntensity[1] = color[1];\r\n\t\t\t\t\tambientColorIntensity[2] = color[2];\r\n\t\t\t\t\tambientColorIntensity[3] = intensity;\r\n\t\t\t\t\treturn ambientColorIntensity;\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn DEFAULT_AMBIENT;\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 * Publishes input events that occur on this Scene's canvas.\r\n\t\t * @property input\r\n\t\t * @type {Input}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.input = new _input_Input_js__WEBPACK_IMPORTED_MODULE_7__.Input(this, {\r\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\r\n\t\t\telement: this.canvas.canvas,\r\n\t\t\tkeyboardEventsElement: cfg.keyboardEventsElement\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\t * Configures this Scene's units of measurement and coordinate mapping between Real-space and World-space 3D coordinate systems.\r\n\t\t *\r\n\t\t * @property metrics\r\n\t\t * @type {Metrics}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.metrics = new _metriqs_Metriqs_js__WEBPACK_IMPORTED_MODULE_17__.Metrics(this, {\r\n\t\t\tunits: cfg.units,\r\n\t\t\tscale: cfg.scale,\r\n\t\t\torigin: cfg.origin\r\n\t\t});\r\n\r\n\t\t/** Configures Scalable Ambient Obscurance (SAO) for this Scene.\r\n\t\t * @type {SAO}\r\n\t\t * @final\r\n\t\t */\r\n\t\tthis.sao = new _postfx_SAO_js__WEBPACK_IMPORTED_MODULE_18__.SAO(this, {\r\n\t\t\tenabled: cfg.saoEnabled\r\n\t\t});\r\n\r\n\t\tthis.ticksPerRender = cfg.ticksPerRender;\r\n\t\tthis.ticksPerOcclusionTest = cfg.ticksPerOcclusionTest;\r\n\t\tthis.passes = cfg.passes;\r\n\t\tthis.clearEachPass = cfg.clearEachPass;\r\n\t\tthis.gammaInput = cfg.gammaInput;\r\n\t\tthis.gammaOutput = cfg.gammaOutput;\r\n\t\tthis.gammaFactor = cfg.gammaFactor;\r\n\r\n\t\tthis._entityOffsetsEnabled = !!cfg.entityOffsetsEnabled;\r\n\t\tthis._logarithmicDepthBufferEnabled = !!cfg.logarithmicDepthBufferEnabled;\r\n\r\n\t\tthis._dtxEnabled = cfg.dtxEnabled !== false;\r\n\t\tthis._pbrEnabled = !!cfg.pbrEnabled;\r\n\t\tthis._colorTextureEnabled = cfg.colorTextureEnabled !== false;\r\n\t\tthis._dtxEnabled = !!cfg.dtxEnabled;\r\n\t\tthis._lodEnabled = cfg.lodEnabled !== false;\r\n\r\n\t\t// Register Scene on xeokit\r\n\t\t// Do this BEFORE we add components below\r\n\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core._addScene(this);\r\n\r\n\t\tthis._initDefaults();\r\n\r\n\t\t// Global components\r\n\r\n\t\tthis._viewport = new _viewport_Viewport_js__WEBPACK_IMPORTED_MODULE_8__.Viewport(this, {\r\n\t\t\tid: \"default.viewport\",\r\n\t\t\tautoBoundary: true,\r\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\r\n\t\t});\r\n\r\n\t\tthis._camera = new _camera_Camera_js__WEBPACK_IMPORTED_MODULE_9__.Camera(this, {\r\n\t\t\tid: \"default.camera\",\r\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\r\n\t\t});\r\n\r\n\t\t// Default lights\r\n\r\n\t\tnew _lights_AmbientLight_js__WEBPACK_IMPORTED_MODULE_11__.AmbientLight(this, {\r\n\t\t\tcolor: [1.0, 1.0, 1.0],\r\n\t\t\tintensity: 0.7\r\n\t\t});\r\n\r\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\r\n\t\t\tdir: [0.8, -0.5, -0.5],\r\n\t\t\tcolor: [0.67, 0.67, 1.0],\r\n\t\t\tintensity: 0.7,\r\n\t\t\tspace: \"world\"\r\n\t\t});\r\n\r\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\r\n\t\t\tdir: [-0.8, -1.0, 0.5],\r\n\t\t\tcolor: [1, 1, 0.9],\r\n\t\t\tintensity: 0.9,\r\n\t\t\tspace: \"world\"\r\n\t\t});\r\n\r\n\t\tthis._camera.on(\"dirty\", () => {\r\n\t\t\tthis._renderer.imageDirty();\r\n\t\t});\r\n\r\n\t\tthis._lod = new _lod_LOD_js__WEBPACK_IMPORTED_MODULE_1__.LOD(this, {\r\n\t\t\tenabled: this._lodEnabled,\r\n\t\t\ttargetFPS: 30\r\n\t\t});\r\n\t}\r\n\r\n\t_initDefaults() {\r\n\t\t// Call this Scene's property accessors to lazy-init their properties\r\n\r\n\t\tlet dummy; // Keeps Codacy happy\r\n\r\n\t\tdummy = this.geometry;\r\n\t\tdummy = this.material;\r\n\t\tdummy = this.xrayMaterial;\r\n\t\tdummy = this.edgeMaterial;\r\n\t\tdummy = this.selectedMaterial;\r\n\t\tdummy = this.highlightMaterial;\r\n\t}\r\n\r\n\t_addComponent(component) {\r\n\t\tif (component.id) {\r\n\t\t\t// Manual ID\r\n\t\t\tif (this.components[component.id]) {\r\n\t\t\t\tthis.error(\r\n\t\t\t\t\t\"Component \" +\r\n\t\t\t\t\t\t_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.inQuotes(component.id) +\r\n\t\t\t\t\t\t\" already exists in Scene - ignoring ID, will randomly-generate instead\"\r\n\t\t\t\t);\r\n\t\t\t\tcomponent.id = null;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (!component.id) {\r\n\t\t\t// Auto ID\r\n\t\t\tif (window.nextID === undefined) {\r\n\t\t\t\twindow.nextID = 0;\r\n\t\t\t}\r\n\t\t\t//component.id = math.createUUID();\r\n\t\t\tcomponent.id = \"__\" + window.nextID++;\r\n\t\t\twhile (this.components[component.id]) {\r\n\t\t\t\tcomponent.id = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.createUUID();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.components[component.id] = component;\r\n\r\n\t\t// Register for class type\r\n\t\tconst type = component.type;\r\n\t\tlet types = this.types[component.type];\r\n\t\tif (!types) {\r\n\t\t\ttypes = this.types[type] = {};\r\n\t\t}\r\n\t\ttypes[component.id] = component;\r\n\r\n\t\tif (component.compile) {\r\n\t\t\tthis._compilables[component.id] = component;\r\n\t\t}\r\n\t\tif (component.isDrawable) {\r\n\t\t\tthis._renderer.addDrawable(component.id, component);\r\n\t\t\tthis._collidables[component.id] = component;\r\n\t\t}\r\n\t}\r\n\r\n\t_removeComponent(component) {\r\n\t\tvar id = component.id;\r\n\t\tvar type = component.type;\r\n\t\tdelete this.components[id];\r\n\t\t// Unregister for types\r\n\t\tconst types = this.types[type];\r\n\t\tif (types) {\r\n\t\t\tdelete types[id];\r\n\t\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isEmptyObject(types)) {\r\n\t\t\t\tdelete this.types[type];\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (component.compile) {\r\n\t\t\tdelete this._compilables[component.id];\r\n\t\t}\r\n\t\tif (component.isDrawable) {\r\n\t\t\tthis._renderer.removeDrawable(component.id);\r\n\t\t\tdelete this._collidables[component.id];\r\n\t\t}\r\n\t}\r\n\r\n\t// Methods below are called by various component types to register themselves on their\r\n\t// Scene. Violates Hollywood Principle, where we could just filter on type in _addComponent,\r\n\t// but this is faster than checking the type of each component in such a filter.\r\n\r\n\t_sectionPlaneCreated(sectionPlane) {\r\n\t\tthis.sectionPlanes[sectionPlane.id] = sectionPlane;\r\n\t\tthis.scene._sectionPlanesState.addSectionPlane(sectionPlane._state);\r\n\t\tthis.scene.fire(\"sectionPlaneCreated\", sectionPlane, true /* Don't retain event */);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_bitmapCreated(bitmap) {\r\n\t\tthis.bitmaps[bitmap.id] = bitmap;\r\n\t\tthis.scene.fire(\"bitmapCreated\", bitmap, true /* Don't retain event */);\r\n\t}\r\n\r\n\t_lineSetCreated(lineSet) {\r\n\t\tthis.lineSets[lineSet.id] = lineSet;\r\n\t\tthis.scene.fire(\"lineSetCreated\", lineSet, true /* Don't retain event */);\r\n\t}\r\n\r\n\t_lightCreated(light) {\r\n\t\tthis.lights[light.id] = light;\r\n\t\tthis.scene._lightsState.addLight(light._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_lightMapCreated(lightMap) {\r\n\t\tthis.lightMaps[lightMap.id] = lightMap;\r\n\t\tthis.scene._lightsState.addLightMap(lightMap._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_reflectionMapCreated(reflectionMap) {\r\n\t\tthis.reflectionMaps[reflectionMap.id] = reflectionMap;\r\n\t\tthis.scene._lightsState.addReflectionMap(reflectionMap._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_sectionPlaneDestroyed(sectionPlane) {\r\n\t\tdelete this.sectionPlanes[sectionPlane.id];\r\n\t\tthis.scene._sectionPlanesState.removeSectionPlane(sectionPlane._state);\r\n\t\tthis.scene.fire(\"sectionPlaneDestroyed\", sectionPlane, true /* Don't retain event */);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_bitmapDestroyed(bitmap) {\r\n\t\tdelete this.bitmaps[bitmap.id];\r\n\t\tthis.scene.fire(\"bitmapDestroyed\", bitmap, true /* Don't retain event */);\r\n\t}\r\n\r\n\t_lineSetDestroyed(lineSet) {\r\n\t\tdelete this.lineSets[lineSet.id];\r\n\t\tthis.scene.fire(\"lineSetDestroyed\", lineSet, true /* Don't retain event */);\r\n\t}\r\n\r\n\t_lightDestroyed(light) {\r\n\t\tdelete this.lights[light.id];\r\n\t\tthis.scene._lightsState.removeLight(light._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_lightMapDestroyed(lightMap) {\r\n\t\tdelete this.lightMaps[lightMap.id];\r\n\t\tthis.scene._lightsState.removeLightMap(lightMap._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_reflectionMapDestroyed(reflectionMap) {\r\n\t\tdelete this.reflectionMaps[reflectionMap.id];\r\n\t\tthis.scene._lightsState.removeReflectionMap(reflectionMap._state);\r\n\t\tthis._needRecompile = true;\r\n\t}\r\n\r\n\t_registerModel(entity) {\r\n\t\tthis.models[entity.id] = entity;\r\n\t\tthis._modelIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deregisterModel(entity) {\r\n\t\tconst modelId = entity.id;\r\n\t\tdelete this.models[modelId];\r\n\t\tthis._modelIds = null; // Lazy regenerate\r\n\t\tthis.fire(\"modelUnloaded\", modelId);\r\n\t}\r\n\r\n\t_registerObject(entity) {\r\n\t\tthis.objects[entity.id] = entity;\r\n\t\tthis._numObjects++;\r\n\t\tthis._objectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deregisterObject(entity) {\r\n\t\tdelete this.objects[entity.id];\r\n\t\tthis._numObjects--;\r\n\t\tthis._objectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectVisibilityUpdated(entity, notify = true) {\r\n\t\tif (entity.visible) {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.visibleObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=true)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthis.visibleObjects[entity.id] = entity;\r\n\t\t\tthis._numVisibleObjects++;\r\n\t\t} else {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.visibleObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=false)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tdelete this.visibleObjects[entity.id];\r\n\t\t\tthis._numVisibleObjects--;\r\n\t\t}\r\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\r\n\t\tif (notify) {\r\n\t\t\tthis.fire(\"objectVisibility\", entity, true);\r\n\t\t}\r\n\t}\r\n\r\n\t_deRegisterVisibleObject(entity) {\r\n\t\tdelete this.visibleObjects[entity.id];\r\n\t\tthis._numVisibleObjects--;\r\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectXRayedUpdated(entity, notify = true) {\r\n\t\tif (entity.xrayed) {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.xrayedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=true)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthis.xrayedObjects[entity.id] = entity;\r\n\t\t\tthis._numXRayedObjects++;\r\n\t\t} else {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.xrayedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=false)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tdelete this.xrayedObjects[entity.id];\r\n\t\t\tthis._numXRayedObjects--;\r\n\t\t}\r\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\r\n\t\tif (notify) {\r\n\t\t\tthis.fire(\"objectXRayed\", entity, true);\r\n\t\t}\r\n\t}\r\n\r\n\t_deRegisterXRayedObject(entity) {\r\n\t\tdelete this.xrayedObjects[entity.id];\r\n\t\tthis._numXRayedObjects--;\r\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectHighlightedUpdated(entity) {\r\n\t\tif (entity.highlighted) {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.highlightedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=true)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthis.highlightedObjects[entity.id] = entity;\r\n\t\t\tthis._numHighlightedObjects++;\r\n\t\t} else {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.highlightedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=false)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tdelete this.highlightedObjects[entity.id];\r\n\t\t\tthis._numHighlightedObjects--;\r\n\t\t}\r\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deRegisterHighlightedObject(entity) {\r\n\t\tdelete this.highlightedObjects[entity.id];\r\n\t\tthis._numHighlightedObjects--;\r\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectSelectedUpdated(entity, notify = true) {\r\n\t\tif (entity.selected) {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.selectedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object select update (selected=true)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthis.selectedObjects[entity.id] = entity;\r\n\t\t\tthis._numSelectedObjects++;\r\n\t\t} else {\r\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.selectedObjects[entity.id]) {\r\n\t\t\t\tconsole.error(\"Redundant object select update (selected=false)\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tdelete this.selectedObjects[entity.id];\r\n\t\t\tthis._numSelectedObjects--;\r\n\t\t}\r\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\r\n\t\tif (notify) {\r\n\t\t\tthis.fire(\"objectSelected\", entity, true);\r\n\t\t}\r\n\t}\r\n\r\n\t_deRegisterSelectedObject(entity) {\r\n\t\tdelete this.selectedObjects[entity.id];\r\n\t\tthis._numSelectedObjects--;\r\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectColorizeUpdated(entity, colorized) {\r\n\t\tif (colorized) {\r\n\t\t\tthis.colorizedObjects[entity.id] = entity;\r\n\t\t\tthis._numColorizedObjects++;\r\n\t\t} else {\r\n\t\t\tdelete this.colorizedObjects[entity.id];\r\n\t\t\tthis._numColorizedObjects--;\r\n\t\t}\r\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deRegisterColorizedObject(entity) {\r\n\t\tdelete this.colorizedObjects[entity.id];\r\n\t\tthis._numColorizedObjects--;\r\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectOpacityUpdated(entity, opacityUpdated) {\r\n\t\tif (opacityUpdated) {\r\n\t\t\tthis.opacityObjects[entity.id] = entity;\r\n\t\t\tthis._numOpacityObjects++;\r\n\t\t} else {\r\n\t\t\tdelete this.opacityObjects[entity.id];\r\n\t\t\tthis._numOpacityObjects--;\r\n\t\t}\r\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deRegisterOpacityObject(entity) {\r\n\t\tdelete this.opacityObjects[entity.id];\r\n\t\tthis._numOpacityObjects--;\r\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_objectOffsetUpdated(entity, offset) {\r\n\t\tif (!offset || (offset[0] === 0 && offset[1] === 0 && offset[2] === 0)) {\r\n\t\t\tthis.offsetObjects[entity.id] = entity;\r\n\t\t\tthis._numOffsetObjects++;\r\n\t\t} else {\r\n\t\t\tdelete this.offsetObjects[entity.id];\r\n\t\t\tthis._numOffsetObjects--;\r\n\t\t}\r\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_deRegisterOffsetObject(entity) {\r\n\t\tdelete this.offsetObjects[entity.id];\r\n\t\tthis._numOffsetObjects--;\r\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\r\n\t}\r\n\r\n\t_webglContextLost() {\r\n\t\t// this.loading++;\r\n\t\tthis.canvas.spinner.processes++;\r\n\t\tfor (const id in this.components) {\r\n\t\t\tif (this.components.hasOwnProperty(id)) {\r\n\t\t\t\tconst component = this.components[id];\r\n\t\t\t\tif (component._webglContextLost) {\r\n\t\t\t\t\tcomponent._webglContextLost();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._renderer.webglContextLost();\r\n\t}\r\n\r\n\t_webglContextRestored() {\r\n\t\tconst gl = this.canvas.gl;\r\n\t\tfor (const id in this.components) {\r\n\t\t\tif (this.components.hasOwnProperty(id)) {\r\n\t\t\t\tconst component = this.components[id];\r\n\t\t\t\tif (component._webglContextRestored) {\r\n\t\t\t\t\tcomponent._webglContextRestored(gl);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._renderer.webglContextRestored(gl);\r\n\t\t//this.loading--;\r\n\t\tthis.canvas.spinner.processes--;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the capabilities of this Scene.\r\n\t *\r\n\t * @private\r\n\t * @returns {{astcSupported: boolean, etc1Supported: boolean, pvrtcSupported: boolean, etc2Supported: boolean, dxtSupported: boolean, bptcSupported: boolean}}\r\n\t */\r\n\tget capabilities() {\r\n\t\treturn this._renderer.capabilities;\r\n\t}\r\n\r\n\t/**\r\n\t * Whether {@link Entity#offset} is enabled.\r\n\t *\r\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\r\n\t *\r\n\t * @returns {Boolean} True if {@link Entity#offset} is enabled.\r\n\t */\r\n\tget entityOffsetsEnabled() {\r\n\t\treturn this._entityOffsetsEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Whether precision surface picking is enabled.\r\n\t *\r\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\r\n\t *\r\n\t * The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.\r\n\t *\r\n\t * Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer.\r\n\t *\r\n\t * @returns {Boolean} True if precision picking is enabled.\r\n\t */\r\n\tget pickSurfacePrecisionEnabled() {\r\n\t\treturn false; // Removed\r\n\t}\r\n\r\n\t/**\r\n\t * Whether logarithmic depth buffer is enabled.\r\n\t *\r\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\r\n\t *\r\n\t * @returns {Boolean} True if logarithmic depth buffer is enabled.\r\n\t */\r\n\tget logarithmicDepthBufferEnabled() {\r\n\t\treturn this._logarithmicDepthBufferEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\r\n\t *\r\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\r\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\r\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\r\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\r\n\t * your expected usage.\r\n\t *\r\n\t * Default is ````0````.\r\n\t */\r\n\tset numCachedSectionPlanes(numCachedSectionPlanes) {\r\n\t\tnumCachedSectionPlanes = numCachedSectionPlanes || 0;\r\n\t\tif (this._sectionPlanesState.getNumCachedSectionPlanes() !== numCachedSectionPlanes) {\r\n\t\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(numCachedSectionPlanes);\r\n\t\t\tthis._needRecompile = true;\r\n\t\t\tthis.glRedraw();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\r\n\t *\r\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\r\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\r\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\r\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\r\n\t * your expected usage.\r\n\t *\r\n\t * Default is ````0````.\r\n\t *\r\n\t * @returns {number} The number of {@link SectionPlane}s for which this Scene pre-caches resources.\r\n\t */\r\n\tget numCachedSectionPlanes() {\r\n\t\treturn this._sectionPlanesState.getNumCachedSectionPlanes();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether physically-based rendering is enabled.\r\n\t *\r\n\t * Default is ````false````.\r\n\t */\r\n\tset pbrEnabled(pbrEnabled) {\r\n\t\tthis._pbrEnabled = !!pbrEnabled;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether physically-based rendering is enabled.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @returns {Boolean} True if quality rendering is enabled.\r\n\t */\r\n\tget pbrEnabled() {\r\n\t\treturn this._pbrEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether data texture scene representation (DTX) is enabled for the {@link Scene}.\r\n\t *\r\n\t * Even when enabled, DTX will only work if supported.\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tset dtxEnabled(value) {\r\n\t\tvalue = !!value;\r\n\t\tif (this._dtxEnabled === value) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._dtxEnabled = value;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether data texture-based scene representation (DTX) is enabled for the {@link Scene}.\r\n\t *\r\n\t * Even when enabled, DTX will only apply if supported.\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tget dtxEnabled() {\r\n\t\treturn this._dtxEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * set showedges enable\r\n\t * @param {boolean} edgesEnabled\r\n\t */\r\n\tset edgesEnabled(edgesEnabled) {\r\n\t\tedgesEnabled = !!edgesEnabled;\r\n\t\tif (this._edgesEnabled === edgesEnabled) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._edgesEnabled = edgesEnabled;\r\n\t\tthis._renderer.setEdgesEnabled(edgesEnabled);\r\n\t}\r\n\r\n\t/**\r\n\t * @param {boolean} trans\r\n\t */\r\n\tget edgesEnabled() {\r\n\t\treturn this._edgesEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * set whether transparent of canvas background\r\n\t * @param {boolean} trans\r\n\t */\r\n\tset backgroundTransparent(trans) {\r\n\t\ttrans = !!trans;\r\n\t\t// if (this._transparent == trans) {\r\n\t\t// return;\r\n\t\t// }\r\n\t\tthis._transparent = trans;\r\n\t\tthis._renderer.setTransparentEnabled(trans);\r\n\t}\r\n\r\n\t/**\r\n\t * @returns {boolean} backgroundTransparent\r\n\t */\r\n\tget backgroundTransparent() {\r\n\t\treturn this._transparent;\r\n\t}\r\n\r\n\t/**\r\n\t * set background color\r\n\t * @param {[]} color\r\n\t */\r\n\tset backgroundColor(color) {\r\n\t\tthis.canvas.backgroundColor = color;\r\n\t\tthis._renderer.render({ force: true });\r\n\t}\r\n\r\n\t/**\r\n\t * return backgroundColor\r\n\t * @returns {boolean} backgroundColor\r\n\t */\r\n\tget backgroundColor() {\r\n\t\treturn this.canvas.backgroundColor();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether basic color texture rendering is enabled.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\r\n\t */\r\n\tset colorTextureEnabled(colorTextureEnabled) {\r\n\t\tthis._colorTextureEnabled = !!colorTextureEnabled;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether basic color texture rendering is enabled.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\r\n\t */\r\n\tget colorTextureEnabled() {\r\n\t\treturn this._colorTextureEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Performs an occlusion test on all {@link Marker}s in this {@link Scene}.\r\n\t *\r\n\t * Sets each {@link Marker#visible} ````true```` if the Marker is currently not occluded by any opaque {@link Entity}s\r\n\t * in the Scene, or ````false```` if an Entity is occluding it.\r\n\t */\r\n\tdoOcclusionTest() {\r\n\t\tif (this._needRecompile) {\r\n\t\t\tthis._recompile();\r\n\t\t\tthis._needRecompile = false;\r\n\t\t}\r\n\t\tthis._renderer.doOcclusionTest();\r\n\t}\r\n\r\n\t/**\r\n\t * Renders a single frame of this Scene.\r\n\t *\r\n\t * The Scene will periodically render itself after any updates, but you can call this method to force a render\r\n\t * if required.\r\n\t *\r\n\t * @param {Boolean} [forceRender=false] Forces a render when true, otherwise only renders if something has changed in this Scene\r\n\t * since the last render.\r\n\t */\r\n\trender(forceRender) {\r\n\t\tif (forceRender) {\r\n\t\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core.runTasks();\r\n\t\t}\r\n\r\n\t\tconst renderEvent = {\r\n\t\t\tsceneId: null,\r\n\t\t\tpass: 0\r\n\t\t};\r\n\r\n\t\tif (this._needRecompile) {\r\n\t\t\tthis._recompile();\r\n\t\t\tthis._renderer.imageDirty();\r\n\t\t\tthis._needRecompile = false;\r\n\t\t}\r\n\r\n\t\tif (!forceRender && !this._renderer.needsRender()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\trenderEvent.sceneId = this.id;\r\n\r\n\t\tconst passes = this._passes;\r\n\t\tconst clearEachPass = this._clearEachPass;\r\n\t\tlet pass;\r\n\t\tlet clear;\r\n\r\n\t\tfor (pass = 0; pass < passes; pass++) {\r\n\t\t\trenderEvent.pass = pass;\r\n\r\n\t\t\t/**\r\n\t\t\t * Fired when about to render a frame for a Scene.\r\n\t\t\t *\r\n\t\t\t * @event rendering\r\n\t\t\t * @param {String} sceneID The ID of this Scene.\r\n\t\t\t * @param {Number} pass Index of the pass we are about to render (see {@link Scene#passes}).\r\n\t\t\t */\r\n\t\t\tthis.fire(\"rendering\", renderEvent, true);\r\n\r\n\t\t\tclear = clearEachPass || pass === 0;\r\n\r\n\t\t\tthis._renderer.render({ pass: pass, clear: clear, force: forceRender });\r\n\r\n\t\t\t/**\r\n\t\t\t * Fired when we have just rendered a frame for a Scene.\r\n\t\t\t *\r\n\t\t\t * @event rendering\r\n\t\t\t * @param {String} sceneID The ID of this Scene.\r\n\t\t\t * @param {Number} pass Index of the pass we rendered (see {@link Scene#passes}).\r\n\t\t\t */\r\n\t\t\tthis.fire(\"rendered\", renderEvent, true);\r\n\t\t}\r\n\r\n\t\tthis._saveAmbientColor();\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tcompile() {\r\n\t\tif (this._needRecompile) {\r\n\t\t\tthis._recompile();\r\n\t\t\tthis._renderer.imageDirty();\r\n\t\t\tthis._needRecompile = false;\r\n\t\t}\r\n\t}\r\n\r\n\t_recompile() {\r\n\t\tfor (const id in this._compilables) {\r\n\t\t\tif (this._compilables.hasOwnProperty(id)) {\r\n\t\t\t\tthis._compilables[id].compile();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._renderer.shadowsDirty();\r\n\t\tthis.fire(\"compile\", this, true);\r\n\t}\r\n\r\n\t_saveAmbientColor() {\r\n\t\tconst canvas = this.canvas;\r\n\t\tif (!canvas.transparent && !canvas.backgroundImage && !canvas.backgroundColor) {\r\n\t\t\tconst ambientColorIntensity = this._lightsState.getAmbientColorAndIntensity();\r\n\t\t\tif (\r\n\t\t\t\t!this._lastAmbientColor ||\r\n\t\t\t\tthis._lastAmbientColor[0] !== ambientColorIntensity[0] ||\r\n\t\t\t\tthis._lastAmbientColor[1] !== ambientColorIntensity[1] ||\r\n\t\t\t\tthis._lastAmbientColor[2] !== ambientColorIntensity[2] ||\r\n\t\t\t\tthis._lastAmbientColor[3] !== ambientColorIntensity[3]\r\n\t\t\t) {\r\n\t\t\t\tcanvas.backgroundColor = ambientColorIntensity;\r\n\t\t\t\tif (!this._lastAmbientColor) {\r\n\t\t\t\t\tthis._lastAmbientColor = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 1]);\r\n\t\t\t\t}\r\n\t\t\t\tthis._lastAmbientColor.set(ambientColorIntensity);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis._lastAmbientColor = null;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#models}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget modelIds() {\r\n\t\tif (!this._modelIds) {\r\n\t\t\tthis._modelIds = Object.keys(this.models);\r\n\t\t}\r\n\t\treturn this._modelIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#objects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numObjects() {\r\n\t\treturn this._numObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#objects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget objectIds() {\r\n\t\tif (!this._objectIds) {\r\n\t\t\tthis._objectIds = Object.keys(this.objects);\r\n\t\t}\r\n\t\treturn this._objectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#visibleObjects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numVisibleObjects() {\r\n\t\treturn this._numVisibleObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#visibleObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget visibleObjectIds() {\r\n\t\tif (!this._visibleObjectIds) {\r\n\t\t\tthis._visibleObjectIds = Object.keys(this.visibleObjects);\r\n\t\t}\r\n\t\treturn this._visibleObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#xrayedObjects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numXRayedObjects() {\r\n\t\treturn this._numXRayedObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#xrayedObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget xrayedObjectIds() {\r\n\t\tif (!this._xrayedObjectIds) {\r\n\t\t\tthis._xrayedObjectIds = Object.keys(this.xrayedObjects);\r\n\t\t}\r\n\t\treturn this._xrayedObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#highlightedObjects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numHighlightedObjects() {\r\n\t\treturn this._numHighlightedObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#highlightedObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget highlightedObjectIds() {\r\n\t\tif (!this._highlightedObjectIds) {\r\n\t\t\tthis._highlightedObjectIds = Object.keys(this.highlightedObjects);\r\n\t\t}\r\n\t\treturn this._highlightedObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#selectedObjects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numSelectedObjects() {\r\n\t\treturn this._numSelectedObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#selectedObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget selectedObjectIds() {\r\n\t\tif (!this._selectedObjectIds) {\r\n\t\t\tthis._selectedObjectIds = Object.keys(this.selectedObjects);\r\n\t\t}\r\n\t\treturn this._selectedObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of {@link Entity}s in {@link Scene#colorizedObjects}.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget numColorizedObjects() {\r\n\t\treturn this._numColorizedObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#colorizedObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget colorizedObjectIds() {\r\n\t\tif (!this._colorizedObjectIds) {\r\n\t\t\tthis._colorizedObjectIds = Object.keys(this.colorizedObjects);\r\n\t\t}\r\n\t\treturn this._colorizedObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#opacityObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget opacityObjectIds() {\r\n\t\tif (!this._opacityObjectIds) {\r\n\t\t\tthis._opacityObjectIds = Object.keys(this.opacityObjects);\r\n\t\t}\r\n\t\treturn this._opacityObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#offsetObjects}.\r\n\t *\r\n\t * @type {String[]}\r\n\t */\r\n\tget offsetObjectIds() {\r\n\t\tif (!this._offsetObjectIds) {\r\n\t\t\tthis._offsetObjectIds = Object.keys(this.offsetObjects);\r\n\t\t}\r\n\t\treturn this._offsetObjectIds;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the number of \"ticks\" that happen between each render or this Scene.\r\n\t *\r\n\t * Default value is ````1````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tset ticksPerRender(value) {\r\n\t\tif (value === undefined || value === null) {\r\n\t\t\tvalue = 1;\r\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\r\n\t\t\tthis.error(\"Unsupported value for 'ticksPerRender': '\" + value + \"' - should be an integer greater than zero.\");\r\n\t\t\tvalue = 1;\r\n\t\t}\r\n\t\tif (value === this._ticksPerRender) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._ticksPerRender = value;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of \"ticks\" that happen between each render or this Scene.\r\n\t *\r\n\t * Default value is ````1````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget ticksPerRender() {\r\n\t\treturn this._ticksPerRender;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the number of \"ticks\" that happen between occlusion testing for {@link Marker}s.\r\n\t *\r\n\t * Default value is ````20````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tset ticksPerOcclusionTest(value) {\r\n\t\tif (value === undefined || value === null) {\r\n\t\t\tvalue = 20;\r\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\r\n\t\t\tthis.error(\r\n\t\t\t\t\"Unsupported value for 'ticksPerOcclusionTest': '\" + value + \"' - should be an integer greater than zero.\"\r\n\t\t\t);\r\n\t\t\tvalue = 20;\r\n\t\t}\r\n\t\tif (value === this._ticksPerOcclusionTest) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._ticksPerOcclusionTest = value;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of \"ticks\" that happen between each render of this Scene.\r\n\t *\r\n\t * Default value is ````1````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget ticksPerOcclusionTest() {\r\n\t\treturn this._ticksPerOcclusionTest;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the number of times this Scene renders per frame.\r\n\t *\r\n\t * Default value is ````1````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tset passes(value) {\r\n\t\tif (value === undefined || value === null) {\r\n\t\t\tvalue = 1;\r\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\r\n\t\t\tthis.error(\"Unsupported value for 'passes': '\" + value + \"' - should be an integer greater than zero.\");\r\n\t\t\tvalue = 1;\r\n\t\t}\r\n\t\tif (value === this._passes) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._passes = value;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the number of times this Scene renders per frame.\r\n\t *\r\n\t * Default value is ````1````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget passes() {\r\n\t\treturn this._passes;\r\n\t}\r\n\r\n\t/**\r\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````).\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tset clearEachPass(value) {\r\n\t\tvalue = !!value;\r\n\t\tif (value === this._clearEachPass) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._clearEachPass = value;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\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````).\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tget clearEachPass() {\r\n\t\treturn this._clearEachPass;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tset gammaInput(value) {\r\n\t\tvalue = value !== false;\r\n\t\tif (value === this._renderer.gammaInput) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._renderer.gammaInput = value;\r\n\t\tthis._needRecompile = true;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tget gammaInput() {\r\n\t\treturn this._renderer.gammaInput;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether or not to render pixels with pre-multiplied gama.\r\n\t *\r\n\t * Default value is ````false````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tset gammaOutput(value) {\r\n\t\tvalue = !!value;\r\n\t\tif (value === this._renderer.gammaOutput) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._renderer.gammaOutput = value;\r\n\t\tthis._needRecompile = true;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether or not to render pixels with pre-multiplied gama.\r\n\t *\r\n\t * Default value is ````true````.\r\n\t *\r\n\t * @type {Boolean}\r\n\t */\r\n\tget gammaOutput() {\r\n\t\treturn this._renderer.gammaOutput;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the gamma factor to use when {@link Scene#gammaOutput} is set true.\r\n\t *\r\n\t * Default value is ````2.2````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tset gammaFactor(value) {\r\n\t\tvalue = value === undefined || value === null ? 2.2 : value;\r\n\t\tif (value === this._renderer.gammaFactor) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._renderer.gammaFactor = value;\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the gamma factor to use when {@link Scene#gammaOutput} is set true.\r\n\t *\r\n\t * Default value is ````2.2````.\r\n\t *\r\n\t * @type {Number}\r\n\t */\r\n\tget gammaFactor() {\r\n\t\treturn this._renderer.gammaFactor;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default {@link Geometry} for this Scene, which is a {@link ReadableGeometry} with a unit-sized box shape.\r\n\t *\r\n\t * Has {@link ReadableGeometry#id} set to \"default.geometry\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#geometry} set to this {@link ReadableGeometry} by default.\r\n\t *\r\n\t * @type {ReadableGeometry}\r\n\t */\r\n\tget geometry() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.geometry\"] ||\r\n\t\t\t(0,_geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_13__.buildBoxGeometry)(_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_12__.ReadableGeometry, this, {\r\n\t\t\t\tid: \"default.geometry\",\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default {@link Material} for this Scene, which is a {@link PhongMaterial}.\r\n\t *\r\n\t * Has {@link PhongMaterial#id} set to \"default.material\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#material} set to this {@link PhongMaterial} by default.\r\n\t *\r\n\t * @type {PhongMaterial}\r\n\t */\r\n\tget material() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.material\"] ||\r\n\t\t\tnew _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_14__.PhongMaterial(this, {\r\n\t\t\t\tid: \"default.material\",\r\n\t\t\t\temissive: [0.4, 0.4, 0.4], // Visible by default on geometry without normals\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default xraying {@link EmphasisMaterial} for this Scene.\r\n\t *\r\n\t * Has {@link EmphasisMaterial#id} set to \"default.xrayMaterial\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#xrayMaterial} set to this {@link EmphasisMaterial} by default.\r\n\t *\r\n\t * {@link Mesh}s are xrayed while {@link Mesh#xrayed} is ````true````.\r\n\t *\r\n\t * @type {EmphasisMaterial}\r\n\t */\r\n\tget xrayMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.xrayMaterial\"] ||\r\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\r\n\t\t\t\tid: \"default.xrayMaterial\",\r\n\t\t\t\tpreset: \"sepia\",\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default highlight {@link EmphasisMaterial} for this Scene.\r\n\t *\r\n\t * Has {@link EmphasisMaterial#id} set to \"default.highlightMaterial\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\r\n\t *\r\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\r\n\t *\r\n\t * @type {EmphasisMaterial}\r\n\t */\r\n\tget highlightMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.highlightMaterial\"] ||\r\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\r\n\t\t\t\tid: \"default.highlightMaterial\",\r\n\t\t\t\tpreset: \"yellowHighlight\",\r\n\t\t\t\tfillAlpha: 0.1,\r\n\t\t\t\tfillColor: [0.7, 0.9, 0.9],\r\n\t\t\t\tdontClear: false,\r\n\t\t\t\tedges: false,\r\n\t\t\t\tglowThrough: false\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default selection {@link EmphasisMaterial} for this Scene.\r\n\t *\r\n\t * Has {@link EmphasisMaterial#id} set to \"default.selectedMaterial\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\r\n\t *\r\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\r\n\t *\r\n\t * @type {EmphasisMaterial}\r\n\t */\r\n\tget selectedMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.selectedMaterial\"] ||\r\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\r\n\t\t\t\tid: \"default.selectedMaterial\",\r\n\t\t\t\tpreset: \"greenSelected\",\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the default {@link EdgeMaterial} for this Scene.\r\n\t *\r\n\t * Has {@link EdgeMaterial#id} set to \"default.edgeMaterial\".\r\n\t *\r\n\t * {@link Mesh}s in this Scene have {@link Mesh#edgeMaterial} set to this {@link EdgeMaterial} by default.\r\n\t *\r\n\t * {@link Mesh}s have their edges emphasized while {@link Mesh#edges} is ````true````.\r\n\t *\r\n\t * @type {EdgeMaterial}\r\n\t */\r\n\tget edgeMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.edgeMaterial\"] ||\r\n\t\t\tnew _materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_16__.EdgeMaterial(this, {\r\n\t\t\t\tid: \"default.edgeMaterial\",\r\n\t\t\t\tpreset: \"default\",\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\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link PointsMaterial} for this Scene.\r\n\t *\r\n\t * @type {PointsMaterial}\r\n\t */\r\n\tget pointsMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.pointsMaterial\"] ||\r\n\t\t\tnew _materials_PointsMaterial_js__WEBPACK_IMPORTED_MODULE_19__.PointsMaterial(this, {\r\n\t\t\t\tid: \"default.pointsMaterial\",\r\n\t\t\t\tpreset: \"default\",\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link LinesMaterial} for this Scene.\r\n\t *\r\n\t * @type {LinesMaterial}\r\n\t */\r\n\tget linesMaterial() {\r\n\t\treturn (\r\n\t\t\tthis.components[\"default.linesMaterial\"] ||\r\n\t\t\tnew _materials_LinesMaterial_js__WEBPACK_IMPORTED_MODULE_20__.LinesMaterial(this, {\r\n\t\t\t\tid: \"default.linesMaterial\",\r\n\t\t\t\tpreset: \"default\",\r\n\t\t\t\tdontClear: true\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link Viewport} for this Scene.\r\n\t *\r\n\t * @type Viewport\r\n\t */\r\n\tget viewport() {\r\n\t\treturn this._viewport;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link Camera} for this Scene.\r\n\t *\r\n\t * @type {Camera}\r\n\t */\r\n\tget camera() {\r\n\t\treturn this._camera;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the World-space 3D center of this Scene.\r\n\t *\r\n\t *@type {Number[]}\r\n\t */\r\n\tget center() {\r\n\t\tif (this._aabbDirty || !this._center) {\r\n\t\t\tif (!this._center || !this._center) {\r\n\t\t\t\tthis._center = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec3();\r\n\t\t\t}\r\n\t\t\tconst aabb = this.aabb;\r\n\t\t\tthis._center[0] = (aabb[0] + aabb[3]) / 2;\r\n\t\t\tthis._center[1] = (aabb[1] + aabb[4]) / 2;\r\n\t\t\tthis._center[2] = (aabb[2] + aabb[5]) / 2;\r\n\t\t}\r\n\t\treturn this._center;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the World-space axis-aligned 3D boundary (AABB) of this Scene.\r\n\t *\r\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]````.\r\n\t *\r\n\t * When the Scene has no content, will be ````[-100,-100,-100,100,100,100]````.\r\n\t *\r\n\t * @type {Number[]}\r\n\t */\r\n\tget aabb() {\r\n\t\tif (this._aabbDirty) {\r\n\t\t\tif (!this._aabb) {\r\n\t\t\t\tthis._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\r\n\t\t\t}\r\n\t\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\t\tlet aabb;\r\n\t\t\tconst collidables = this._collidables;\r\n\t\t\tlet collidable;\r\n\t\t\tlet valid = false;\r\n\t\t\tfor (const collidableId in collidables) {\r\n\t\t\t\tif (collidables.hasOwnProperty(collidableId)) {\r\n\t\t\t\t\tcollidable = collidables[collidableId];\r\n\t\t\t\t\tif (collidable.collidable === false) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\taabb = collidable.aabb;\r\n\t\t\t\t\tif (aabb[0] < xmin) {\r\n\t\t\t\t\t\txmin = aabb[0];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (aabb[1] < ymin) {\r\n\t\t\t\t\t\tymin = aabb[1];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (aabb[2] < zmin) {\r\n\t\t\t\t\t\tzmin = aabb[2];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (aabb[3] > xmax) {\r\n\t\t\t\t\t\txmax = aabb[3];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (aabb[4] > ymax) {\r\n\t\t\t\t\t\tymax = aabb[4];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (aabb[5] > zmax) {\r\n\t\t\t\t\t\tzmax = aabb[5];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvalid = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!valid) {\r\n\t\t\t\txmin = -100;\r\n\t\t\t\tymin = -100;\r\n\t\t\t\tzmin = -100;\r\n\t\t\t\txmax = 100;\r\n\t\t\t\tymax = 100;\r\n\t\t\t\tzmax = 100;\r\n\t\t\t}\r\n\t\t\tthis._aabb[0] = xmin;\r\n\t\t\tthis._aabb[1] = ymin;\r\n\t\t\tthis._aabb[2] = zmin;\r\n\t\t\tthis._aabb[3] = xmax;\r\n\t\t\tthis._aabb[4] = ymax;\r\n\t\t\tthis._aabb[5] = zmax;\r\n\t\t\tthis._aabbDirty = false;\r\n\t\t}\r\n\t\treturn this._aabb;\r\n\t}\r\n\r\n\t_setAABBDirty() {\r\n\t\t//if (!this._aabbDirty) {\r\n\t\tthis._aabbDirty = true;\r\n\t\tthis.fire(\"boundary\");\r\n\t\t// }\r\n\t}\r\n\r\n\t/**\r\n * Attempts to pick an {@link Entity} in this Scene.\r\n *\r\n * Ignores {@link Entity}s with {@link Entity#pickable} set ````false````.\r\n *\r\n * When an {@link Entity} is picked, fires a \"pick\" event on the {@link Entity} with the pick result as parameters.\r\n *\r\n * Picking the {@link Entity} at the given canvas coordinates:\r\n\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * canvasPos: [23, 131]\r\n * });\r\n *\r\n * if (pickResult) { // Picked an Entity\r\n * var entity = pickResult.entity;\r\n * }\r\n * ````\r\n *\r\n * Picking, with a ray cast through the canvas, hits an {@link Entity}:\r\n *\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * pickSurface: true,\r\n * canvasPos: [23, 131]\r\n * });\r\n *\r\n * if (pickResult) { // Picked an Entity\r\n *\r\n * var entity = pickResult.entity;\r\n *\r\n * if (pickResult.primitive === \"triangle\") {\r\n *\r\n * // Picked a triangle on the entity surface\r\n *\r\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\r\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\r\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\r\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\r\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\r\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\r\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\r\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\r\n *\r\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\r\n *\r\n * // Picked a point and normal on the entity surface\r\n *\r\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\r\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\r\n * }\r\n * }\r\n * ````\r\n *\r\n * Picking the {@link Entity} that intersects an arbitrarily-aligned World-space ray:\r\n *\r\n * ````javascript\r\n * var pickResult = scene.pick({\r\n * pickSurface: true, // Picking with arbitrarily-positioned ray\r\n * origin: [0,0,-5], // Ray origin\r\n * direction: [0,0,1] // Ray direction\r\n * });\r\n *\r\n * if (pickResult) { // Picked an Entity with the ray\r\n *\r\n * var entity = pickResult.entity;\r\n *\r\n * if (pickResult.primitive == \"triangle\") {\r\n *\r\n * // Picked a triangle on the entity surface\r\n *\r\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\r\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\r\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\r\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\r\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\r\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\r\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\r\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\r\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\r\n * var origin = pickResult.origin; // Float64Array containing the World-space ray origin\r\n * var direction = pickResult.direction; // Float64Array containing the World-space ray direction\r\n *\r\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\r\n *\r\n * // Picked a point and normal on the entity surface\r\n *\r\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\r\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\r\n * }\r\n * }\r\n * ````\r\n *\r\n * @param {*} params Picking parameters.\r\n * @param {Boolean} [params.pickSurface=false] Whether to find the picked position on the surface of the Entity.\r\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.\r\n * @param {Boolean} [params.pickSurfaceNormal=false] Whether to find the picked normal on the surface of the Entity. Only works if ````pickSurface```` is given.\r\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.\r\n * @param {Number[]} [params.origin] World-space ray origin when ray-picking. Ignored when canvasPos given.\r\n * @param {Number[]} [params.direction] World-space ray direction when ray-picking. Also indicates the length of the ray. Ignored when canvasPos given.\r\n * @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.\r\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.\r\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.\r\n * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\r\n * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\r\n * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\r\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.\r\n * @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.\r\n */\r\n\tpick(params, pickResult) {\r\n\t\tif (this.canvas.boundary[2] === 0 || this.canvas.boundary[3] === 0) {\r\n\t\t\tthis.error(\"Picking not allowed while canvas has zero width or height\");\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tparams = params || {};\r\n\r\n\t\tparams.pickSurface = params.pickSurface || params.rayPick; // Backwards compatibility\r\n\r\n\t\tif (!params.canvasPos && !params.matrix && (!params.origin || !params.direction)) {\r\n\t\t\tthis.warn(\"picking without canvasPos, matrix, or ray origin and direction\");\r\n\t\t}\r\n\r\n\t\tconst includeEntities = params.includeEntities || params.include; // Backwards compat\r\n\t\tif (includeEntities) {\r\n\t\t\tparams.includeEntityIds = getEntityIDMap(this, includeEntities);\r\n\t\t}\r\n\r\n\t\tconst excludeEntities = params.excludeEntities || params.exclude; // Backwards compat\r\n\t\tif (excludeEntities) {\r\n\t\t\tparams.excludeEntityIds = getEntityIDMap(this, excludeEntities);\r\n\t\t}\r\n\r\n\t\tif (this._needRecompile) {\r\n\t\t\tthis._recompile();\r\n\t\t\tthis._renderer.imageDirty();\r\n\t\t\tthis._needRecompile = false;\r\n\t\t}\r\n\r\n\t\tif (params.snapToEdge || params.snapToVertex) {\r\n\t\t\tpickResult = this._renderer.snapPick(\r\n\t\t\t\tparams.canvasPos,\r\n\t\t\t\tparams.snapRadius || 30,\r\n\t\t\t\tparams.snapToVertex,\r\n\t\t\t\tparams.snapToEdge,\r\n\t\t\t\tpickResult\r\n\t\t\t);\r\n\t\t} else {\r\n\t\t\tpickResult = this._renderer.pick(params, pickResult);\r\n\t\t}\r\n\r\n\t\tif (pickResult) {\r\n\t\t\tif (pickResult.entity && pickResult.entity.fire) {\r\n\t\t\t\tpickResult.entity.fire(\"picked\", pickResult); // TODO: SceneModelEntity doesn't fire events\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn pickResult;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {Object} params Picking parameters.\r\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.\r\n\t * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\r\n\t * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\r\n\t * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\r\n\t * @deprecated\r\n\t */\r\n\tsnapPick(params) {\r\n\t\tif (undefined === this._warnSnapPickDeprecated) {\r\n\t\t\tthis._warnSnapPickDeprecated = true;\r\n\t\t\tthis.warn(\"Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead\");\r\n\t\t}\r\n\t\treturn this._renderer.snapPick(params.canvasPos, params.snapRadius || 30, params.snapToVertex, params.snapToEdge);\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all non-default {@link Component}s in this Scene.\r\n\t */\r\n\tclear() {\r\n\t\tvar component;\r\n\t\tfor (const id in this.components) {\r\n\t\t\tif (this.components.hasOwnProperty(id)) {\r\n\t\t\t\tcomponent = this.components[id];\r\n\t\t\t\tif (!component._dontClear) {\r\n\t\t\t\t\t// Don't destroy components like Camera, Input, Viewport etc.\r\n\t\t\t\t\tcomponent.destroy();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link Light}s in this Scene..\r\n\t */\r\n\tclearLights() {\r\n\t\tconst ids = Object.keys(this.lights);\r\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.lights[ids[i]].destroy();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link SectionPlane}s in this Scene.\r\n\t */\r\n\tclearSectionPlanes() {\r\n\t\tconst ids = Object.keys(this.sectionPlanes);\r\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.sectionPlanes[ids[i]].destroy();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link Line}s in this Scene.\r\n\t */\r\n\tclearBitmaps() {\r\n\t\tconst ids = Object.keys(this.bitmaps);\r\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.bitmaps[ids[i]].destroy();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link Line}s in this Scene.\r\n\t */\r\n\tclearLines() {\r\n\t\tconst ids = Object.keys(this.lineSets);\r\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.lineSets[ids[i]].destroy();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the collective axis-aligned boundary (AABB) of a batch of {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * Each {@link Entity} on which {@link Entity#isObject} is registered by {@link Entity#id} in {@link Scene#visibleObjects}.\r\n\t *\r\n\t * Each {@link Entity} is only included in the AABB when {@link Entity#collidable} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\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]````.\r\n\t */\r\n\tgetAABB(ids) {\r\n\t\tif (ids === undefined) {\r\n\t\t\treturn this.aabb;\r\n\t\t}\r\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\r\n\t\t\tconst entity = this.objects[ids];\r\n\t\t\tif (entity && entity.aabb) {\r\n\t\t\t\t// A Component subclass with an AABB\r\n\t\t\t\treturn entity.aabb;\r\n\t\t\t}\r\n\t\t\tids = [ids]; // Must be an entity type\r\n\t\t}\r\n\t\tif (ids.length === 0) {\r\n\t\t\treturn this.aabb;\r\n\t\t}\r\n\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\r\n\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\r\n\t\tlet valid;\r\n\t\tthis.withObjects(ids, (entity) => {\r\n\t\t\tif (entity.collidable) {\r\n\t\t\t\tconst aabb = entity.aabb;\r\n\t\t\t\tif (aabb[0] < xmin) {\r\n\t\t\t\t\txmin = aabb[0];\r\n\t\t\t\t}\r\n\t\t\t\tif (aabb[1] < ymin) {\r\n\t\t\t\t\tymin = aabb[1];\r\n\t\t\t\t}\r\n\t\t\t\tif (aabb[2] < zmin) {\r\n\t\t\t\t\tzmin = aabb[2];\r\n\t\t\t\t}\r\n\t\t\t\tif (aabb[3] > xmax) {\r\n\t\t\t\t\txmax = aabb[3];\r\n\t\t\t\t}\r\n\t\t\t\tif (aabb[4] > ymax) {\r\n\t\t\t\t\tymax = aabb[4];\r\n\t\t\t\t}\r\n\t\t\t\tif (aabb[5] > zmax) {\r\n\t\t\t\t\tzmax = aabb[5];\r\n\t\t\t\t}\r\n\t\t\t\tvalid = true;\r\n\t\t\t}\r\n\t\t});\r\n\t\tif (valid) {\r\n\t\t\tconst aabb2 = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\r\n\t\t\taabb2[0] = xmin;\r\n\t\t\taabb2[1] = ymin;\r\n\t\t\taabb2[2] = zmin;\r\n\t\t\taabb2[3] = xmax;\r\n\t\t\taabb2[4] = ymax;\r\n\t\t\taabb2[5] = zmax;\r\n\t\t\treturn aabb2;\r\n\t\t} else {\r\n\t\t\treturn this.aabb; // Scene AABB\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#visible} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#visible} are ````true```` is\r\n\t * registered by {@link Entity#id} in {@link Scene#visibleObjects}.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} visible Whether or not to set visible.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsVisible(ids, visible) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.visible !== visible;\r\n\t\t\tentity.visible = visible;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#collidable} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} collidable Whether or not to set collidable.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsCollidable(ids, collidable) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.collidable !== collidable;\r\n\t\t\tentity.collidable = collidable;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#culled} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} culled Whether or not to cull.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsCulled(ids, culled) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.culled !== culled;\r\n\t\t\tentity.culled = culled;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#selected} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#selected} are ````true```` is\r\n\t * registered by {@link Entity#id} in {@link Scene#selectedObjects}.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} selected Whether or not to select.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsSelected(ids, selected) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.selected !== selected;\r\n\t\t\tentity.selected = selected;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#highlighted} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#highlighted} are ````true```` is\r\n\t * registered by {@link Entity#id} in {@link Scene#highlightedObjects}.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} highlighted Whether or not to highlight.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsHighlighted(ids, highlighted) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.highlighted !== highlighted;\r\n\t\t\tentity.highlighted = highlighted;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#xrayed} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} xrayed Whether or not to xray.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsXRayed(ids, xrayed) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.xrayed !== xrayed;\r\n\t\t\tentity.xrayed = xrayed;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#edges} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} edges Whether or not to show edges.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsEdges(ids, edges) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.edges !== edges;\r\n\t\t\tentity.edges = edges;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#colorize} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Number[]} [colorize=(1,1,1)] RGB colorize factors, multiplied by the rendered pixel colors.\r\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsColorized(ids, colorize) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tentity.colorize = colorize;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#opacity} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Number} [opacity=1.0] Opacity factor, multiplied by the rendered pixel alphas.\r\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsOpacity(ids, opacity) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.opacity !== opacity;\r\n\t\t\tentity.opacity = opacity;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#pickable} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Boolean} pickable Whether or not to set pickable.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\tsetObjectsPickable(ids, pickable) {\r\n\t\treturn this.withObjects(ids, (entity) => {\r\n\t\t\tconst changed = entity.pickable !== pickable;\r\n\t\t\tentity.pickable = pickable;\r\n\t\t\treturn changed;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Batch-updates {@link Entity#offset} on {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Number[]} [offset] 3D offset vector.\r\n\t */\r\n\tsetObjectsOffset(ids, offset) {\r\n\t\tthis.withObjects(ids, (entity) => {\r\n\t\t\tentity.offset = offset;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Iterates with a callback over {@link Entity}s that represent objects.\r\n\t *\r\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\r\n\t *\r\n\t * @param {String[]} ids Array of {@link Entity#id} values.\r\n\t * @param {Function} callback Callback to execute on eacn {@link Entity}.\r\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\r\n\t */\r\n\twithObjects(ids, callback) {\r\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\r\n\t\t\tids = [ids];\r\n\t\t}\r\n\t\tlet changed = false;\r\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tconst id = ids[i];\r\n\t\t\tlet entity = this.objects[id];\r\n\t\t\tif (entity) {\r\n\t\t\t\tchanged = callback(entity) || changed;\r\n\t\t\t} else {\r\n\t\t\t\tconst modelIds = this.modelIds;\r\n\t\t\t\tfor (let i = 0, len = modelIds.length; i < len; i++) {\r\n\t\t\t\t\tconst modelId = modelIds[i];\r\n\t\t\t\t\tconst globalObjectId = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.globalizeObjectId(modelId, id);\r\n\t\t\t\t\tentity = this.objects[globalObjectId];\r\n\t\t\t\t\tif (entity) {\r\n\t\t\t\t\t\tchanged = callback(entity) || changed;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn changed;\r\n\t}\r\n\r\n\t/**\r\n\t * This method will \"tickify\" the provided `cb` function.\r\n\t *\r\n\t * This means, the function will be wrapped so:\r\n\t *\r\n\t * - it runs time-aligned to scene ticks\r\n\t * - it runs maximum once per scene-tick\r\n\t *\r\n\t * @param {Function} cb The function to tickify\r\n\t * @returns {Function}\r\n\t */\r\n\ttickify(cb) {\r\n\t\tconst cbString = cb.toString();\r\n\r\n\t\t/**\r\n\t\t * Check if the function is already tickified, and if so return the cached one.\r\n\t\t */\r\n\t\tif (cbString in this._tickifiedFunctions) {\r\n\t\t\treturn this._tickifiedFunctions[cbString].wrapperFunc;\r\n\t\t}\r\n\r\n\t\tlet alreadyRun = 0;\r\n\t\tlet needToRun = 0;\r\n\r\n\t\tlet lastArgs;\r\n\r\n\t\t/**\r\n\t\t * The provided `cb` function is replaced with a \"set-dirty\" function\r\n\t\t *\r\n\t\t * @type {Function}\r\n\t\t */\r\n\t\tconst wrapperFunc = function (...args) {\r\n\t\t\tlastArgs = args;\r\n\t\t\tneedToRun++;\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * An each scene tick, if the \"dirty-flag\" is set, run the `cb` function.\r\n\t\t *\r\n\t\t * This will make it run time-aligned to the scene tick.\r\n\t\t */\r\n\t\tconst tickSubId = this.on(\"tick\", () => {\r\n\t\t\tconst tmp = needToRun;\r\n\t\t\tif (tmp > alreadyRun) {\r\n\t\t\t\talreadyRun = tmp;\r\n\t\t\t\tcb(...lastArgs);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\t * And, store the list of subscribers.\r\n\t\t */\r\n\t\tthis._tickifiedFunctions[cbString] = { tickSubId, wrapperFunc };\r\n\r\n\t\treturn wrapperFunc;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this Scene.\r\n\t */\r\n\tdestroy(callback) {\r\n\t\tsuper.destroy();\r\n\t\tfor (const id in this.components) {\r\n\t\t\tif (this.components.hasOwnProperty(id)) {\r\n\t\t\t\tthis.components[id].destroy();\r\n\t\t\t}\r\n\t\t}\r\n\t\t// this.canvas.destroy(); // canvas是scene的其中一个component,所有以不必再destroy\r\n\r\n\t\t// Memory leak prevention\r\n\t\tthis.components = null;\r\n\t\tthis.models = null;\r\n\t\tthis.objects = null;\r\n\t\tthis.visibleObjects = null;\r\n\t\tthis.xrayedObjects = null;\r\n\t\tthis.highlightedObjects = null;\r\n\t\tthis.selectedObjects = null;\r\n\t\tthis.colorizedObjects = null;\r\n\t\tthis.opacityObjects = null;\r\n\t\tthis.sectionPlanes = null;\r\n\t\tthis.lights = null;\r\n\t\tthis.lightMaps = null;\r\n\t\tthis.reflectionMaps = null;\r\n\t\tthis._objectIds = null;\r\n\t\tthis._visibleObjectIds = null;\r\n\t\tthis._xrayedObjectIds = null;\r\n\t\tthis._highlightedObjectIds = null;\r\n\t\tthis._selectedObjectIds = null;\r\n\t\tthis._colorizedObjectIds = null;\r\n\t\tthis.types = null;\r\n\t\tthis._renderer = null;\r\n\t\tthis.input = null;\r\n\t\tthis._viewport = null;\r\n\t\tthis._camera = null;\r\n\t\tthis.canvas = null;\r\n\t\tif (typeof callback === \"function\") {\r\n\t\t\tcallback();\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/scene/Scene.js?");
|
|
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});\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(\"xeokit 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?");
|
|
4808
4808
|
|
|
4809
4809
|
/***/ }),
|
|
4810
4810
|
|