From 0f338abeba97d1b4050d942ea7a71a00c5dd8a6b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 10 Apr 2024 19:16:34 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=20MRjs=20-=20Auto=20Generated=20Di?= =?UTF-8?q?st=20=F0=9F=91=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes from `github.com/Volumetrics-io/mrjs` at 70494db99029a5ac2a7b294bb9c1c54280f0214f -includes folder updates: `static/dist` -runs smoo.sh before committing --- source/static/dist/mr.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/static/dist/mr.js b/source/static/dist/mr.js index 332e0cd..d9a832c 100644 --- a/source/static/dist/mr.js +++ b/source/static/dist/mr.js @@ -465,7 +465,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MREntity: () => (/* binding */ MREntity)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mrjs/core/MRElement */ \"./src/core/MRElement.js\");\n/* harmony import */ var mrjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! mrjs */ \"./src/index.js\");\n\n\n\n\n\n\nconst MOUSE_EVENTS = ['click', 'mouseenter', 'mouseleave', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove'];\n\n/**\n * @class MREntity\n * @classdesc The default representation of an MRElement to be expanded upon by actual details ECS Entity items. `mr-entity`\n * @augments MRElement\n */\nclass MREntity extends mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__.MRElement {\n aabb = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n\n size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n layer = 0;\n\n physics = {\n type: 'none',\n };\n\n /**\n * @class\n * @description Constructor for the default Entity Component (MREntity).\n * Sets up the base object3D and useful Mixed Reality information including rendering, touching, and component basics.\n */\n constructor() {\n super();\n\n this.object3D = new three__WEBPACK_IMPORTED_MODULE_2__.Group();\n this.object3D.userData.isEntityObject3DRoot = true;\n this.object3D.userData.bbox = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n this.object3D.userData.size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n this.object3D.receiveShadow = true;\n this.object3D.castShadow = true;\n this.object3D.renderOrder = 3;\n this.object3D.name = 'entity';\n\n this.scale = 1;\n\n this.componentMutated = this.componentMutated.bind(this);\n\n this.touch = false;\n this.grabbed = false;\n this.focus = false;\n\n this.ignoreStencil = true;\n }\n\n /*************************/\n /*** Object Dimensions ***/\n /*************************/\n\n /**\n * @function\n * @description Calculates the width of the Entity based on the viewPort's shape. If in Mixed Reality, adjusts the value appropriately.\n * @returns {number} - the resolved width\n */\n get width() {\n return (this.compStyle.width.split('px')[0] / __webpack_require__.g.appWidth) * __webpack_require__.g.viewPortWidth;\n }\n\n /**\n * @function\n * @description The actual 3D value of the content's width.\n * @returns {number} - width of the 3D object.\n */\n get contentWidth() {\n this.aabb.setFromObject(this.object3D).getSize(this.size);\n return this.size.x;\n }\n\n /**\n * @function\n * @description Calculates the height of the Entity based on the viewPort's shape. If in Mixed Reality, adjusts the value appropriately.\n * @returns {number} - the resolved height\n */\n get height() {\n return (this.compStyle.height.split('px')[0] / __webpack_require__.g.appHeight) * __webpack_require__.g.viewPortHeight;\n }\n\n /**\n * @function\n * @description The actual 3D value of the content's height.\n * @returns {number} - height of the 3D object.\n */\n get contentHeight() {\n this.aabb.setFromObject(this.object3D).getSize(this.size);\n return this.size.y;\n }\n\n /****************************/\n /*** Updates And Triggers ***/\n /****************************/\n\n /**\n * @function\n * @description Triggers a system run to update geometry specifically for the entity calling it. Useful when it's not an overall scene event and for cases where\n * relying on an overall scene or all items to update isnt beneficial.\n */\n triggerGeometryStyleUpdate() {\n this.dispatchEvent(new CustomEvent('trigger-geometry-style-update', { detail: this, bubbles: true }));\n }\n\n /**\n * @function\n * @description Triggers a system run to update material specifically for the entity calling it. Useful when it's not an overall scene event and for cases where\n * relying on an overall scene or all items to update isnt beneficial.\n */\n triggerMaterialStyleUpdate() {\n this.dispatchEvent(new CustomEvent('trigger-material-style-update', { detail: this, bubbles: true }));\n }\n\n /**\n * @function\n * @description Directly in MRjs, this function is empty. It is called directly in the\n * MaterialStyleSystem. This allows outside users to add their own additional functionality\n * for the entities. These are run after the MaterialStyleSystem does its own update on the entity.\n */\n updateMaterialStyle() {}\n\n /**\n * @function\n * @description Directly in MRjs, this function is empty. It is called directly in the\n * GeometryStyleSystem. This allows outside users to add their own additional functionality\n * for the entities. These are run after the GeometryStyleSystem does its own update on the entity.\n */\n updateGeometryStyle() {}\n\n /*****************************/\n /*** On Interaction Events ***/\n /*****************************/\n\n /**\n * @function\n * @description Handles the hover event\n * @param {object} event - the hover event\n */\n onHover = (event) => {};\n\n /**\n * @function\n * @description Handles the touch event\n * @param {object} event - the touch event\n */\n onTouch = (event) => {};\n\n /**\n * @function\n * @description Handles the scroll event\n * @param {object} event - the scroll event\n */\n onScroll = (event) => {\n this.parentElement?.onScroll(event);\n };\n\n /********************************/\n /*** Handling data-attributes ***/\n /********************************/\n\n components = {\n get: (name) => {\n const dataName = `comp${name[0].toUpperCase()}${name.slice(1)}`;\n return mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToJson(this.dataset[dataName]);\n },\n\n set: (name, data) => {\n const dataName = `comp${name[0].toUpperCase()}${name.slice(1)}`;\n const component = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToJson(this.dataset[dataName]) ?? {};\n for (const key in data) {\n component[key] = data[key];\n }\n this.dataset[dataName] = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.jsonToString(component);\n },\n };\n\n position = {\n get: () => {\n return this.dataset.position;\n },\n\n set: (arr) => {\n if (arr.length != 3) {\n mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.error.err('position must be set with an array of all three elements [x, y, z]');\n }\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position ?? '0 0 0');\n vec[0] = arr[0];\n vec[1] = arr[1];\n vec[2] = arr[2];\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n x: () => {\n return this.dataset.position.split(' ')[0];\n },\n\n setX: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[0] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n y: () => {\n return this.dataset.position.split(' ')[1];\n },\n\n setY: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[1] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n z: () => {\n return this.dataset.position.split(' ')[2];\n },\n\n setZ: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[2] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n };\n\n rotation = {\n get: () => {\n return this.dataset.rotation;\n },\n\n set: (arr) => {\n if (arr.length != 3) {\n mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.error.err('rotation must be set with an array of all three elements [x, y, z]');\n }\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation ?? '0 0 0');\n vec[0] = arr[0];\n vec[1] = arr[1];\n vec[2] = arr[2];\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n x: () => {\n return this.dataset.rotation.split(' ')[0];\n },\n\n x: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[0] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n y: () => {\n return this.dataset.rotation.split(' ')[1];\n },\n\n y: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[1] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n z: () => {\n return this.dataset.rotation.split(' ')[2];\n },\n\n z: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[2] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n };\n\n /**\n * @function\n * @description Loads all attributes of this entity's stored dataset including components, attaching them, and their associated rotations and positions.\n */\n loadAttributes() {\n for (const attr in this.dataset) {\n if (attr.includes('comp')) {\n const compName = attr.split('comp')[1].toLocaleLowerCase();\n this.dispatchEvent(\n new CustomEvent(`${attr}-attached`, {\n bubbles: true,\n detail: { entity: this },\n })\n );\n } else {\n switch (attr) {\n case 'rotation':\n this.object3D.rotation.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToDegVector(this.dataset.rotation));\n break;\n case 'position':\n this.object3D.position.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position));\n break;\n }\n }\n }\n }\n\n /************************************/\n /*** Handling Entity Interactions ***/\n /************************************/\n\n /**\n * @function\n * @description (async) does nothing. Is called by the connectedCallback.\n */\n async connected() {}\n\n /**\n * @function\n * @description The connectedCallback function that runs whenever this entity component becomes connected to something else.\n */\n async connectedCallback() {\n this.compStyle = window.getComputedStyle(this);\n\n if (!(this.parentElement instanceof mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__.MRElement)) {\n return;\n }\n this.parentElement.add(this);\n\n if (this.parentElement.user) {\n this.user = this.parentElement.user;\n }\n if (this.parentElement.env) {\n this.env = this.parentElement.env;\n }\n\n this.object3D.userData.element = this;\n\n this.object3D.userData.bbox = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n this.object3D.userData.size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n this.object3D.userData.bbox.setFromObject(this.object3D);\n\n this.object3D.userData.bbox.getSize(this.object3D.userData.size);\n\n this.mutationCallback = this.mutationCallback.bind(this);\n this.observer = new MutationObserver(this.mutationCallback);\n this.observer.observe(this, { attributes: true, childList: true, attributeOldValue: true });\n\n /** Handle events specific to this entity */\n // note: these will need the trigger for Material or Geometry if applicable\n\n MOUSE_EVENTS.forEach((eventType) => {\n this.addEventListener(eventType, (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n });\n });\n\n this.addEventListener('touchstart', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('touchmove', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('touchend', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('hoverstart', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onHover(event);\n });\n this.addEventListener('hoverend', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onHover(event);\n });\n\n this.addEventListener('child-updated', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n });\n\n // TODO: find alternative solution. This breaks with the switch to asychronous entity initialization\n // const intersectionObserver = new IntersectionObserver((entries) => {\n // for (const entry of entries) {\n // this._boundingClientRect = entry.boundingClientRect;\n // }\n // // Refresh the rect info to keep it up-to-date as much as possible.\n // // It seems that the callback is always called once soon after observe() is called,\n // // regardless of the intersection state of the entity.\n // // TODO: Confirm whether this behavior is intended. If it is not, there may be future\n // // behavior changes or it may not work as intended on certain platforms.\n // intersectionObserver.disconnect();\n // intersectionObserver.observe(this);\n // });\n // intersectionObserver.observe(this);\n\n // If the physics not yet inititalized, set an event listener and wait til the engine\n // has started before completing initialization\n if (mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.physics.initialized) {\n await this.connected();\n this.loadAttributes();\n this.dispatchEvent(new CustomEvent('entityadded', { bubbles: true }));\n } else {\n document.addEventListener('engine-started', async (event) => {\n await this.connected();\n this.loadAttributes();\n this.dispatchEvent(new CustomEvent('entityadded', { bubbles: true }));\n });\n }\n }\n\n /**\n * @function\n * @description Callback function of MREntity - does nothing. Is called by the disconnectedCallback.\n */\n disconnected() {}\n\n /**\n * @function\n * @description The disconnectedCallback function that runs whenever this entity component becomes disconnected from something else.\n */\n disconnectedCallback() {\n document.dispatchEvent(\n new CustomEvent('entityremoved', {\n detail: {\n entity: this,\n },\n })\n );\n\n this.environment = null;\n this.observer.disconnect();\n\n this.disconnected();\n }\n\n /**\n * @function\n * @description Callback function of MREntity - does nothing. Is called by mutation Callback.\n * @param {object} mutation - the update/change/mutation to be handled.\n */\n mutated(mutation) {}\n\n /**\n * @function\n * @description The mutationCallback function that runs whenever this entity component should be mutated.\n * @param {object} mutationList - the list of update/change/mutation(s) to be handled.\n * @param {object} observer - w3 standard object that watches for changes on the HTMLElement\n */\n mutationCallback(mutationList, observer) {\n for (const mutation of mutationList) {\n this.mutated(mutation);\n\n switch (mutation.type) {\n case 'childList':\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n break;\n case 'attributes':\n if (mutation.attributeName.includes('comp')) {\n this.componentMutated(mutation);\n }\n switch (mutation.attributeName) {\n case 'data-position':\n this.object3D.position.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position));\n break;\n case 'data-rotation':\n this.object3D.rotation.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToDegVector(this.dataset.rotation));\n break;\n\n default:\n break;\n }\n break;\n\n default:\n break;\n }\n }\n }\n\n /**\n * @function\n * @description Helper function for the mutationCallback. Handles actually updating this entity component with all the associated dispatchEvents.\n * @param {object} mutation - the update/change/mutation to be handled.\n */\n componentMutated(mutation) {\n const compName = mutation.attributeName.split('comp-')[1];\n const dataName = `comp${compName[0].toUpperCase()}${compName.slice(1)}`;\n if (!this.dataset[dataName]) {\n this.dispatchEvent(new CustomEvent(`${dataName}-detached`, { bubbles: true }));\n } else if (mutation.oldValue) {\n this.dispatchEvent(\n new CustomEvent(`${dataName}-updated`, {\n bubbles: true,\n detail: { oldData: mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.jsonToString(mutation.oldValue) },\n })\n );\n } else {\n this.dispatchEvent(\n new CustomEvent(`${dataName}-attached`, {\n bubbles: true,\n })\n );\n }\n }\n\n /**\n * @function\n * @description Adding an entity as a sub-object of this entity.\n * @param {MREntity} entity - the entity to be added.\n */\n add(entity) {\n entity.object3D.receiveShadow = true;\n entity.object3D.renderOrder = 3;\n this.object3D.add(entity.object3D);\n }\n\n /**\n * @function\n * @description Removing an entity as a sub-object of this entity.\n * @param {MREntity} entity - the entity to be removed.\n */\n removeEntity(entity) {\n this.object3D.remove(entity.object3D);\n }\n\n /**\n * @function\n * @description Runs the passed through function on this object and every child of this object.\n * @param {Function} callBack - the function to run recursively.\n */\n traverse(callBack) {\n callBack(this);\n const children = Array.from(this.children);\n for (const child of children) {\n // if child is an entity, traverse it again\n if (child instanceof MREntity) {\n child.traverse(callBack);\n }\n }\n }\n\n /**\n * @function\n * @description Runs the passed through function on the objects associated with this Entity\n * @param {Function} callBack - the function to run recursively.\n */\n traverseObjects(callBack) {\n const traverse = (object) => {\n callBack(object);\n for (const child of object.children) {\n if (!child.userData.isEntityObject3DRoot) {\n traverse(child);\n }\n }\n };\n traverse(this.object3D);\n }\n}\n\ncustomElements.get('mr-entity') || customElements.define('mr-entity', MREntity);\n\n\n//# sourceURL=webpack://mrjs/./src/core/MREntity.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MREntity: () => (/* binding */ MREntity)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mrjs/core/MRElement */ \"./src/core/MRElement.js\");\n/* harmony import */ var mrjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! mrjs */ \"./src/index.js\");\n\n\n\n\n\n\nconst MOUSE_EVENTS = ['click', 'mouseenter', 'mouseleave', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove'];\n\n/**\n * @class MREntity\n * @classdesc The default representation of an MRElement to be expanded upon by actual details ECS Entity items. `mr-entity`\n * @augments MRElement\n */\nclass MREntity extends mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__.MRElement {\n aabb = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n\n size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n layer = 0;\n\n physics = {\n type: 'none',\n };\n\n /**\n * @class\n * @description Constructor for the default Entity Component (MREntity).\n * Sets up the base object3D and useful Mixed Reality information including rendering, touching, and component basics.\n */\n constructor() {\n super();\n\n this.object3D = new three__WEBPACK_IMPORTED_MODULE_2__.Group();\n this.object3D.userData.isEntityObject3DRoot = true;\n this.object3D.userData.bbox = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n this.object3D.userData.size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n this.object3D.receiveShadow = true;\n this.object3D.castShadow = true;\n this.object3D.renderOrder = 3;\n this.object3D.name = 'entity';\n\n this.scale = 1;\n\n this.componentMutated = this.componentMutated.bind(this);\n\n this.touch = false;\n this.grabbed = false;\n this.focus = false;\n\n this.ignoreStencil = true;\n }\n\n /*************************/\n /*** Object Dimensions ***/\n /*************************/\n\n /**\n * @function\n * @description Calculates the width of the Entity based on the viewPort's shape. If in Mixed Reality, adjusts the value appropriately.\n * @returns {number} - the resolved width\n */\n get width() {\n return (this.compStyle.width.split('px')[0] / __webpack_require__.g.appWidth) * __webpack_require__.g.viewPortWidth;\n }\n\n /**\n * @function\n * @description The actual 3D value of the content's width.\n * @returns {number} - width of the 3D object.\n */\n get contentWidth() {\n this.aabb.setFromObject(this.object3D).getSize(this.size);\n return this.size.x;\n }\n\n /**\n * @function\n * @description Calculates the height of the Entity based on the viewPort's shape. If in Mixed Reality, adjusts the value appropriately.\n * @returns {number} - the resolved height\n */\n get height() {\n return (this.compStyle.height.split('px')[0] / __webpack_require__.g.appHeight) * __webpack_require__.g.viewPortHeight;\n }\n\n /**\n * @function\n * @description The actual 3D value of the content's height.\n * @returns {number} - height of the 3D object.\n */\n get contentHeight() {\n this.aabb.setFromObject(this.object3D).getSize(this.size);\n return this.size.y;\n }\n\n /****************************/\n /*** Updates And Triggers ***/\n /****************************/\n\n /**\n * @function\n * @description Triggers a system run to update geometry specifically for the entity calling it. Useful when it's not an overall scene event and for cases where\n * relying on an overall scene or all items to update isnt beneficial.\n */\n triggerGeometryStyleUpdate() {\n this.dispatchEvent(new CustomEvent('trigger-geometry-style-update', { detail: this, bubbles: true }));\n }\n\n /**\n * @function\n * @description Triggers a system run to update material specifically for the entity calling it. Useful when it's not an overall scene event and for cases where\n * relying on an overall scene or all items to update isnt beneficial.\n */\n triggerMaterialStyleUpdate() {\n this.dispatchEvent(new CustomEvent('trigger-material-style-update', { detail: this, bubbles: true }));\n }\n\n /**\n * @function\n * @description Directly in MRjs, this function is empty. It is called directly in the\n * MaterialStyleSystem. This allows outside users to add their own additional functionality\n * for the entities. These are run after the MaterialStyleSystem does its own update on the entity.\n */\n updateMaterialStyle() {}\n\n /**\n * @function\n * @description Directly in MRjs, this function is empty. It is called directly in the\n * GeometryStyleSystem. This allows outside users to add their own additional functionality\n * for the entities. These are run after the GeometryStyleSystem does its own update on the entity.\n */\n updateGeometryStyle() {}\n\n /*****************************/\n /*** On Interaction Events ***/\n /*****************************/\n\n /**\n * @function\n * @description Handles the hover event\n * @param {object} event - the hover event\n */\n onHover = (event) => {};\n\n /**\n * @function\n * @description Handles the touch event\n * @param {object} event - the touch event\n */\n onTouch = (event) => {};\n\n /**\n * @function\n * @description Handles the scroll event\n * @param {object} event - the scroll event\n */\n onScroll = (event) => {\n this.parentElement?.onScroll(event);\n };\n\n /********************************/\n /*** Handling data-attributes ***/\n /********************************/\n\n components = {\n get: (name) => {\n const dataName = `comp${name[0].toUpperCase()}${name.slice(1)}`;\n return mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToJson(this.dataset[dataName]);\n },\n\n set: (name, data) => {\n const dataName = `comp${name[0].toUpperCase()}${name.slice(1)}`;\n const component = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToJson(this.dataset[dataName]) ?? {};\n for (const key in data) {\n component[key] = data[key];\n }\n this.dataset[dataName] = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.jsonToString(component);\n },\n\n toJSON: () => {\n let all = {}\n for (const key in this.dataset) {\n let compName = key.split('comp')[1]\n if(compName) {\n all[compName.toLowerCase()] = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToJson(this.dataset[key])\n }\n }\n return all\n }\n };\n\n position = {\n get: () => {\n return mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n },\n\n set: (arr) => {\n if (arr.length != 3) {\n mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.error.err('position must be set with an array of all three elements [x, y, z]');\n }\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position ?? '0 0 0');\n vec[0] = arr[0];\n vec[1] = arr[1];\n vec[2] = arr[2];\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n x: () => {\n return this.dataset.position.split(' ')[0];\n },\n\n setX: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[0] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n y: () => {\n return this.dataset.position.split(' ')[1];\n },\n\n setY: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[1] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n z: () => {\n return this.dataset.position.split(' ')[2];\n },\n\n setZ: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n vec[2] = val;\n this.dataset.position = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n };\n\n rotation = {\n get: () => {\n return mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position);\n },\n\n set: (arr) => {\n if (arr.length != 3) {\n mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.error.err('rotation must be set with an array of all three elements [x, y, z]');\n }\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation ?? '0 0 0');\n vec[0] = arr[0];\n vec[1] = arr[1];\n vec[2] = arr[2];\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n x: () => {\n return this.dataset.rotation.split(' ')[0];\n },\n\n x: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[0] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n y: () => {\n return this.dataset.rotation.split(' ')[1];\n },\n\n y: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[1] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n\n z: () => {\n return this.dataset.rotation.split(' ')[2];\n },\n\n z: (val) => {\n let vec = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.rotation);\n vec[2] = val;\n this.dataset.rotation = mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.vectorToString(vec);\n },\n };\n\n /**\n * @function\n * @description Loads all attributes of this entity's stored dataset including components, attaching them, and their associated rotations and positions.\n */\n loadAttributes() {\n for (const attr in this.dataset) {\n if (attr.includes('comp')) {\n const compName = attr.split('comp')[1].toLocaleLowerCase();\n this.dispatchEvent(\n new CustomEvent(`${attr}-attached`, {\n bubbles: true,\n detail: { entity: this },\n })\n );\n } else {\n switch (attr) {\n case 'rotation':\n this.object3D.rotation.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToDegVector(this.dataset.rotation));\n break;\n case 'position':\n this.object3D.position.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position));\n break;\n }\n }\n }\n }\n\n /************************************/\n /*** Handling Entity Interactions ***/\n /************************************/\n\n /**\n * @function\n * @description (async) does nothing. Is called by the connectedCallback.\n */\n async connected() {}\n\n /**\n * @function\n * @description The connectedCallback function that runs whenever this entity component becomes connected to something else.\n */\n async connectedCallback() {\n this.compStyle = window.getComputedStyle(this);\n\n if (!(this.parentElement instanceof mrjs_core_MRElement__WEBPACK_IMPORTED_MODULE_0__.MRElement)) {\n return;\n }\n this.parentElement.add(this);\n\n if (this.parentElement.user) {\n this.user = this.parentElement.user;\n }\n if (this.parentElement.env) {\n this.env = this.parentElement.env;\n }\n\n this.object3D.userData.element = this;\n\n this.object3D.userData.bbox = new three__WEBPACK_IMPORTED_MODULE_2__.Box3();\n this.object3D.userData.size = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3();\n\n this.object3D.userData.bbox.setFromObject(this.object3D);\n\n this.object3D.userData.bbox.getSize(this.object3D.userData.size);\n\n this.mutationCallback = this.mutationCallback.bind(this);\n this.observer = new MutationObserver(this.mutationCallback);\n this.observer.observe(this, { attributes: true, childList: true, attributeOldValue: true });\n\n /** Handle events specific to this entity */\n // note: these will need the trigger for Material or Geometry if applicable\n\n MOUSE_EVENTS.forEach((eventType) => {\n this.addEventListener(eventType, (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n });\n });\n\n this.addEventListener('touchstart', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('touchmove', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('touchend', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onTouch(event);\n });\n this.addEventListener('hoverstart', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onHover(event);\n });\n this.addEventListener('hoverend', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n this.onHover(event);\n });\n\n this.addEventListener('child-updated', (event) => {\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n });\n\n // TODO: find alternative solution. This breaks with the switch to asychronous entity initialization\n // const intersectionObserver = new IntersectionObserver((entries) => {\n // for (const entry of entries) {\n // this._boundingClientRect = entry.boundingClientRect;\n // }\n // // Refresh the rect info to keep it up-to-date as much as possible.\n // // It seems that the callback is always called once soon after observe() is called,\n // // regardless of the intersection state of the entity.\n // // TODO: Confirm whether this behavior is intended. If it is not, there may be future\n // // behavior changes or it may not work as intended on certain platforms.\n // intersectionObserver.disconnect();\n // intersectionObserver.observe(this);\n // });\n // intersectionObserver.observe(this);\n\n // If the physics not yet inititalized, set an event listener and wait til the engine\n // has started before completing initialization\n if (mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.physics.initialized) {\n await this.connected();\n this.loadAttributes();\n this.dispatchEvent(new CustomEvent('entityadded', { bubbles: true }));\n } else {\n document.addEventListener('engine-started', async (event) => {\n await this.connected();\n this.loadAttributes();\n this.dispatchEvent(new CustomEvent('entityadded', { bubbles: true }));\n });\n }\n }\n\n /**\n * @function\n * @description Callback function of MREntity - does nothing. Is called by the disconnectedCallback.\n */\n disconnected() {}\n\n /**\n * @function\n * @description The disconnectedCallback function that runs whenever this entity component becomes disconnected from something else.\n */\n disconnectedCallback() {\n document.dispatchEvent(\n new CustomEvent('entityremoved', {\n detail: {\n entity: this,\n },\n })\n );\n\n this.environment = null;\n this.observer.disconnect();\n\n this.disconnected();\n }\n\n /**\n * @function\n * @description Callback function of MREntity - does nothing. Is called by mutation Callback.\n * @param {object} mutation - the update/change/mutation to be handled.\n */\n mutated(mutation) {}\n\n /**\n * @function\n * @description The mutationCallback function that runs whenever this entity component should be mutated.\n * @param {object} mutationList - the list of update/change/mutation(s) to be handled.\n * @param {object} observer - w3 standard object that watches for changes on the HTMLElement\n */\n mutationCallback(mutationList, observer) {\n for (const mutation of mutationList) {\n this.mutated(mutation);\n\n switch (mutation.type) {\n case 'childList':\n this.triggerGeometryStyleUpdate();\n this.triggerMaterialStyleUpdate();\n break;\n case 'attributes':\n if (mutation.attributeName.includes('comp')) {\n this.componentMutated(mutation);\n }\n switch (mutation.attributeName) {\n case 'data-position':\n this.object3D.position.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToVector(this.dataset.position));\n break;\n case 'data-rotation':\n this.object3D.rotation.fromArray(mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.stringToDegVector(this.dataset.rotation));\n break;\n\n default:\n break;\n }\n break;\n\n default:\n break;\n }\n }\n }\n\n /**\n * @function\n * @description Helper function for the mutationCallback. Handles actually updating this entity component with all the associated dispatchEvents.\n * @param {object} mutation - the update/change/mutation to be handled.\n */\n componentMutated(mutation) {\n const compName = mutation.attributeName.split('comp-')[1];\n const dataName = `comp${compName[0].toUpperCase()}${compName.slice(1)}`;\n if (!this.dataset[dataName]) {\n this.dispatchEvent(new CustomEvent(`${dataName}-detached`, { bubbles: true }));\n } else if (mutation.oldValue) {\n this.dispatchEvent(\n new CustomEvent(`${dataName}-updated`, {\n bubbles: true,\n detail: { oldData: mrjs__WEBPACK_IMPORTED_MODULE_1__.mrjsUtils.string.jsonToString(mutation.oldValue) },\n })\n );\n } else {\n this.dispatchEvent(\n new CustomEvent(`${dataName}-attached`, {\n bubbles: true,\n })\n );\n }\n }\n\n /**\n * @function\n * @description Adding an entity as a sub-object of this entity.\n * @param {MREntity} entity - the entity to be added.\n */\n add(entity) {\n entity.object3D.receiveShadow = true;\n entity.object3D.renderOrder = 3;\n this.object3D.add(entity.object3D);\n }\n\n /**\n * @function\n * @description Removing an entity as a sub-object of this entity.\n * @param {MREntity} entity - the entity to be removed.\n */\n removeEntity(entity) {\n this.object3D.remove(entity.object3D);\n }\n\n /**\n * @function\n * @description Runs the passed through function on this object and every child of this object.\n * @param {Function} callBack - the function to run recursively.\n */\n traverse(callBack) {\n callBack(this);\n const children = Array.from(this.children);\n for (const child of children) {\n // if child is an entity, traverse it again\n if (child instanceof MREntity) {\n child.traverse(callBack);\n }\n }\n }\n\n /**\n * @function\n * @description Runs the passed through function on the objects associated with this Entity\n * @param {Function} callBack - the function to run recursively.\n */\n traverseObjects(callBack) {\n const traverse = (object) => {\n callBack(object);\n for (const child of object.children) {\n if (!child.userData.isEntityObject3DRoot) {\n traverse(child);\n }\n }\n };\n traverse(this.object3D);\n }\n}\n\ncustomElements.get('mr-entity') || customElements.define('mr-entity', MREntity);\n\n\n//# sourceURL=webpack://mrjs/./src/core/MREntity.js?"); /***/ }), @@ -1080,7 +1080,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ string: () => (/* binding */ string)\n/* harmony export */ });\n/**\n * @namespace string\n * @description Useful namespace for helping with String utility functions\n */\nlet string = {};\n\n/*******************************************************/\n/************ JSON // String interactions **************/\n/*******************************************************/\n\n/**\n * @function\n * @memberof string\n * @description Converts and formats the inputted string to a json object.\n * @param {string} attrString - the string to be formatted\n * @returns {object} - object in json form\n */\nstring.stringToJson = function (attrString) {\n if (attrString == null) {\n return null;\n }\n const regexPattern = /(\\w+):\\s*([^;]+)/g;\n const jsonObject = {};\n\n let match;\n while ((match = regexPattern.exec(attrString)) !== null) {\n const key = match[1].trim();\n let value = match[2].trim();\n\n // Check value type and convert if necessary\n if (value.includes(' ')) {\n value = value.split(' ').map((v) => parseFloat(v));\n } else if (/^\\d+(\\.\\d+)?$/.test(value)) {\n value = parseFloat(value);\n } else if (value === 'true') {\n value = true;\n } else if (value === 'false') {\n value = false;\n }\n\n jsonObject[key] = value;\n }\n\n return jsonObject;\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts and formats the inputted json object into a string.\n * @param {object} componentData - the json object to be formatted into a string\n * @returns {string} - the string representation of the json object\n */\nstring.jsonToString = function (componentData) {\n let compString = '';\n\n for (const [key, value] of Object.entries(componentData)) {\n let stringValue;\n\n if (Array.isArray(value)) {\n // Convert array of numbers to space-separated string\n stringValue = value.join(' ');\n } else {\n // Use the value directly for numbers and booleans\n stringValue = value.toString();\n }\n\n // Append the key-value pair to the component string\n compString += `${key}: ${stringValue}; `;\n }\n\n return compString.trim();\n};\n\n/****************************************/\n/*********** String to Math *************/\n/****************************************/\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format.\n * @param {string} str - the string to be converted to a vector. Must be of format 'xx xxx xx...'.\n * @returns {object} - the vector version of the inputted string.\n */\nstring.stringToVector = function (str) {\n return str.split(' ').map(Number);\n};\n\nstring.vectorToString = function (arr) {\n let str = '';\n for (let i = 0; i < arr.length; ++i) {\n str += arr[i];\n if (i + 1 != arr.length) {\n str += ' ';\n }\n }\n return str;\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format where the numbers are pre-converted from radians to degrees.\n * @param {string} str - the string to be converted to a vector. Must be of format 'xx xxx xx...'.\n * @returns {object} - the vector version of the inputted string.\n */\nstring.stringToDegVector = function (str) {\n return str.split(' ').map((val) => (parseFloat(val) * Math.PI) / 180);\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format where the numbers are pre-converted from a number to an appropriate representation\n * @param {string} val - the string to be converted to a vector. Must be of format 'x%' or 'x/y'.\n * @returns {number} - the vector version of the inputted string.\n */\nstring.stringToDimensionValue = function (val) {\n if (val.includes('%')) {\n return parseFloat(val) / 100;\n }\n if (val.includes('/')) {\n return parseInt(val.split('/')[0]) / parseInt(val.split('/')[1]);\n }\n return val;\n};\n\n\n\n\n//# sourceURL=webpack://mrjs/./src/utils/String.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ string: () => (/* binding */ string)\n/* harmony export */ });\n/**\n * @namespace string\n * @description Useful namespace for helping with String utility functions\n */\nlet string = {};\n\n/*******************************************************/\n/************ JSON // String interactions **************/\n/*******************************************************/\n\n/**\n * @function\n * @memberof string\n * @description Converts and formats the inputted string to a json object.\n * @param {string} attrString - the string to be formatted\n * @returns {object} - object in json form\n */\nstring.stringToJson = function (attrString) {\n if (attrString == null) {\n return null;\n }\n const regexPattern = /(\\w+):\\s*([^;]+)/g;\n const jsonObject = {};\n\n let match;\n while ((match = regexPattern.exec(attrString)) !== null) {\n const key = match[1].trim();\n let value = match[2].trim();\n\n // Check value type and convert if necessary\n if (value.includes(' ')) {\n value = value.split(' ').map((v) => parseFloat(v));\n } else if (/^\\d+(\\.\\d+)?$/.test(value)) {\n value = parseFloat(value);\n } else if (value === 'true') {\n value = true;\n } else if (value === 'false') {\n value = false;\n }\n\n jsonObject[key] = value;\n }\n\n return jsonObject;\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts and formats the inputted json object into a string.\n * @param {object} componentData - the json object to be formatted into a string\n * @returns {string} - the string representation of the json object\n */\nstring.jsonToString = function (componentData) {\n let compString = '';\n\n for (const [key, value] of Object.entries(componentData)) {\n let stringValue;\n\n if (Array.isArray(value)) {\n // Convert array of numbers to space-separated string\n stringValue = value.join(' ');\n } else {\n // Use the value directly for numbers and booleans\n stringValue = value.toString();\n }\n\n // Append the key-value pair to the component string\n compString += `${key}: ${stringValue}; `;\n }\n\n return compString.trim();\n};\n\n/****************************************/\n/*********** String to Math *************/\n/****************************************/\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format.\n * @param {string} str - the string to be converted to a vector. Must be of format 'xx xxx xx...'.\n * @returns {object} - the vector version of the inputted string.\n */\nstring.stringToVector = function (str) {\n return str?.split(' ').map(Number) ?? null;\n};\n\nstring.vectorToString = function (arr) {\n let str = '';\n for (let i = 0; i < arr.length; ++i) {\n str += arr[i];\n if (i + 1 != arr.length) {\n str += ' ';\n }\n }\n return str;\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format where the numbers are pre-converted from radians to degrees.\n * @param {string} str - the string to be converted to a vector. Must be of format 'xx xxx xx...'.\n * @returns {object} - the vector version of the inputted string.\n */\nstring.stringToDegVector = function (str) {\n return str.split(' ').map((val) => (parseFloat(val) * Math.PI) / 180);\n};\n\n/**\n * @function\n * @memberof string\n * @description Converts a string to vector format where the numbers are pre-converted from a number to an appropriate representation\n * @param {string} val - the string to be converted to a vector. Must be of format 'x%' or 'x/y'.\n * @returns {number} - the vector version of the inputted string.\n */\nstring.stringToDimensionValue = function (val) {\n if (val.includes('%')) {\n return parseFloat(val) / 100;\n }\n if (val.includes('/')) {\n return parseInt(val.split('/')[0]) / parseInt(val.split('/')[1]);\n }\n return val;\n};\n\n\n\n\n//# sourceURL=webpack://mrjs/./src/utils/String.js?"); /***/ }),