diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 1b4d761..46b29b8 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -14,7 +14,7 @@ export default { // can't use setup because it will not be used in sub components // setup() {}, unmounted() { - if (this._parent) this._parent.remove(this.o3d); + this.removeFromParent(); }, methods: { initObject3D(o3d) { @@ -29,18 +29,33 @@ export default { if (this.lookAt) this.o3d.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z); watch(() => this.lookAt, (v) => { this.o3d.lookAt(v.x, v.y, v.z); }, { deep: true }); - // find first viable parent + this._parent = this.getParent(); + if (this.addToParent()) this.$emit('ready', this); + else console.error('Missing parent (Scene, Group...)'); + }, + getParent() { let parent = this.$parent; while (parent) { - if (parent.add) { - parent.add(this.o3d); - this._parent = parent; - break; - } + if (parent.add) return parent; parent = parent.$parent; } - if (!this._parent) console.error('Missing parent (Scene, Group...)'); - else this.$emit('ready', this); + return false; + }, + addToParent(o) { + const o3d = o || this.o3d; + if (this._parent) { + this._parent.add(o3d); + return true; + } + return false; + }, + removeFromParent(o) { + const o3d = o || this.o3d; + if (this._parent) { + this._parent.remove(o3d); + return true; + } + return false; }, add(o) { this.o3d.add(o); }, remove(o) { this.o3d.remove(o); }, diff --git a/src/lights/Light.js b/src/lights/Light.js index d42dacd..829aff1 100644 --- a/src/lights/Light.js +++ b/src/lights/Light.js @@ -15,7 +15,7 @@ export default { // can't use setup because it will not be used in sub components // setup() {}, unmounted() { - if (this.light.target) this.$parent.remove(this.light.target); + if (this.light.target) this.removeFromParent(this.light.target); }, methods: { initLight() { @@ -40,7 +40,7 @@ export default { }); this.initObject3D(this.light); - if (this.light.target) this.$parent.add(this.light.target); + if (this.light.target) this.addToParent(this.light.target); }, }, __hmrId: 'Light', diff --git a/src/lights/RectAreaLight.js b/src/lights/RectAreaLight.js index a154a47..789fb9a 100644 --- a/src/lights/RectAreaLight.js +++ b/src/lights/RectAreaLight.js @@ -23,13 +23,13 @@ export default { if (this.helper) { this.lightHelper = new RectAreaLightHelper(this.light); - this.$parent.add(this.lightHelper); + this.addToParent(this.lightHelper); } this.initLight(); }, unmounted() { - if (this.lightHelper) this.$parent.remove(this.lightHelper); + if (this.lightHelper) this.removeFromParent(this.lightHelper); }, __hmrId: 'RectAreaLight', }; diff --git a/src/meshes/Gem.js b/src/meshes/Gem.js index 9d33be1..47c3c49 100644 --- a/src/meshes/Gem.js +++ b/src/meshes/Gem.js @@ -25,7 +25,8 @@ export default { }, unmounted() { this.three.offBeforeRender(this.updateCubeRT); - if (this.meshBack) this.$parent.remove(this.meshBack); + if (this.cubeCamera) this.removeFromParent(this.cubeCamera); + if (this.meshBack) this.removeFromParent(this.meshBack); if (this.materialBack) this.materialBack.dispose(); }, methods: { @@ -33,7 +34,7 @@ export default { const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); bindProp(this, 'position', this.cubeCamera); - this.$parent.add(this.cubeCamera); + this.addToParent(this.cubeCamera); this.material.side = FrontSide; this.material.envMap = cubeRT.texture; @@ -57,7 +58,7 @@ export default { bindProp(this, 'position', this.meshBack); bindProp(this, 'rotation', this.meshBack); bindProp(this, 'scale', this.meshBack); - this.$parent.add(this.meshBack); + this.addToParent(this.meshBack); }, updateCubeRT() { this.mesh.visible = false; diff --git a/src/meshes/MirrorMesh.js b/src/meshes/MirrorMesh.js index 97d5b97..0d2cda6 100644 --- a/src/meshes/MirrorMesh.js +++ b/src/meshes/MirrorMesh.js @@ -21,13 +21,13 @@ export default { }, unmounted() { this.three.offBeforeRender(this.updateCubeRT); - if (this.cubeCamera) this.$parent.remove(this.cubeCamera); + if (this.cubeCamera) this.removeFromParent(this.cubeCamera); }, methods: { initMirrorMesh() { const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); - this.$parent.add(this.cubeCamera); + this.addToParent(this.cubeCamera); this.material.envMap = cubeRT.texture; this.material.needsUpdate = true; diff --git a/src/meshes/RefractionMesh.js b/src/meshes/RefractionMesh.js index ce0a443..56d28fb 100644 --- a/src/meshes/RefractionMesh.js +++ b/src/meshes/RefractionMesh.js @@ -24,14 +24,14 @@ export default { }, unmounted() { this.three.offBeforeRender(this.updateCubeRT); - if (this.cubeCamera) this.$parent.remove(this.cubeCamera); + if (this.cubeCamera) this.removeFromParent(this.cubeCamera); }, methods: { initMirrorMesh() { const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); bindProp(this, 'position', this.cubeCamera); - this.$parent.add(this.cubeCamera); + this.addToParent(this.cubeCamera); this.material.envMap = cubeRT.texture; this.material.refractionRatio = this.refractionRatio;