1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

Add group (fix #7, close #8)

This commit is contained in:
Kevin Levron 2021-02-21 21:39:35 +01:00
parent 6929700e97
commit adf64ecb6f
10 changed files with 77 additions and 17 deletions

38
src/core/Group.js Normal file
View File

@ -0,0 +1,38 @@
import { Group } from 'three';
import { inject } from 'vue';
import useBindProp from '../use/useBindProp.js';
export default {
inject: ['three', 'scene'],
props: {
position: Object,
rotation: Object,
scale: Object,
},
setup(props) {
const parent = inject('group', inject('scene'));
const group = new Group();
useBindProp(props, 'position', group.position);
useBindProp(props, 'rotation', group.rotation);
useBindProp(props, 'scale', group.scale);
return { parent, group };
},
provide() {
return {
group: this.group,
};
},
created() {
this.parent.add(this.group);
},
unmounted() {
this.parent.remove(this.group);
},
render() {
if (this.$slots.default) {
return this.$slots.default();
}
return [];
},
__hmrId: 'Group',
};

View File

@ -2,4 +2,5 @@ export { default as Renderer } from './Renderer.js';
export { default as OrthographicCamera } from './OrthographicCamera.js'; export { default as OrthographicCamera } from './OrthographicCamera.js';
export { default as PerspectiveCamera } from './PerspectiveCamera.js'; export { default as PerspectiveCamera } from './PerspectiveCamera.js';
export { default as Camera } from './PerspectiveCamera.js'; export { default as Camera } from './PerspectiveCamera.js';
export { default as Group } from './Group.js';
export { default as Scene } from './Scene.js'; export { default as Scene } from './Scene.js';

View File

@ -1,5 +1,5 @@
import { Color } from 'three'; import { Color } from 'three';
import { watch } from 'vue'; import { inject, watch } from 'vue';
import { setFromProp } from '../tools.js'; import { setFromProp } from '../tools.js';
import useBindProp from '../use/useBindProp.js'; import useBindProp from '../use/useBindProp.js';
@ -21,6 +21,11 @@ export default {
shadowMapSize: Object, shadowMapSize: Object,
position: Object, position: Object,
}, },
// can't use setup because it will not be used in sub components
// setup() {},
created() {
this.parent = inject('group', this.scene);
},
mounted() { mounted() {
useBindProp(this, 'position', this.light.position); useBindProp(this, 'position', this.light.position);
@ -43,11 +48,12 @@ export default {
}); });
}); });
this.scene.add(this.light); this.parent.add(this.light);
if (this.light.target) this.scene.add(this.light.target); if (this.light.target) this.parent.add(this.light.target);
}, },
unmounted() { unmounted() {
this.scene.remove(this.light); this.parent.remove(this.light);
if (this.light.target) this.parent.remove(this.light.target);
}, },
render() { render() {
return []; return [];

View File

@ -26,7 +26,7 @@ export default {
}, },
unmounted() { unmounted() {
this.three.offBeforeRender(this.updateCubeRT); this.three.offBeforeRender(this.updateCubeRT);
if (this.meshBack) this.scene.remove(this.meshBack); if (this.meshBack) this.parent.remove(this.meshBack);
if (this.materialBack) this.materialBack.dispose(); if (this.materialBack) this.materialBack.dispose();
}, },
methods: { methods: {
@ -34,7 +34,7 @@ export default {
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
useBindProp(this, 'position', this.cubeCamera.position); useBindProp(this, 'position', this.cubeCamera.position);
this.scene.add(this.cubeCamera); this.parent.add(this.cubeCamera);
this.material.side = FrontSide; this.material.side = FrontSide;
this.material.envMap = cubeRT.texture; this.material.envMap = cubeRT.texture;
@ -58,7 +58,7 @@ export default {
useBindProp(this, 'position', this.meshBack.position); useBindProp(this, 'position', this.meshBack.position);
useBindProp(this, 'rotation', this.meshBack.rotation); useBindProp(this, 'rotation', this.meshBack.rotation);
useBindProp(this, 'scale', this.meshBack.scale); useBindProp(this, 'scale', this.meshBack.scale);
this.scene.add(this.meshBack); this.parent.add(this.meshBack);
}, },
updateCubeRT() { updateCubeRT() {
this.mesh.visible = false; this.mesh.visible = false;

View File

@ -1,5 +1,5 @@
import { InstancedMesh } from 'three'; import { InstancedMesh } from 'three';
import { watch } from 'vue'; import { inject, watch } from 'vue';
import useBindProp from '../use/useBindProp.js'; import useBindProp from '../use/useBindProp.js';
export default { export default {
@ -11,6 +11,9 @@ export default {
castShadow: Boolean, castShadow: Boolean,
receiveShadow: Boolean, receiveShadow: Boolean,
}, },
created() {
this.parent = inject('group', this.scene);
},
provide() { provide() {
return { return {
mesh: this, mesh: this,
@ -25,7 +28,7 @@ export default {
this.initMesh(); this.initMesh();
}, },
unmounted() { unmounted() {
this.scene.remove(this.mesh); this.parent.remove(this.mesh);
}, },
methods: { methods: {
initMesh() { initMesh() {
@ -48,7 +51,7 @@ export default {
// this.mesh.material = this.three.materials[this.materialId]; // this.mesh.material = this.three.materials[this.materialId];
// }); // });
this.scene.add(this.mesh); this.parent.add(this.mesh);
}, },
setGeometry(geometry) { setGeometry(geometry) {
this.geometry = geometry; this.geometry = geometry;

View File

@ -1,5 +1,5 @@
import { Mesh } from 'three'; import { Mesh } from 'three';
import { watch } from 'vue'; import { inject, watch } from 'vue';
import useBindProp from '../use/useBindProp.js'; import useBindProp from '../use/useBindProp.js';
export default { export default {
@ -13,6 +13,11 @@ export default {
castShadow: Boolean, castShadow: Boolean,
receiveShadow: Boolean, receiveShadow: Boolean,
}, },
// can't use setup because it will not be used in sub components
// setup() {},
created() {
this.parent = inject('group', this.scene);
},
provide() { provide() {
return { return {
mesh: this, mesh: this,
@ -24,7 +29,7 @@ export default {
}, },
unmounted() { unmounted() {
// console.log('Mesh unmounted'); // console.log('Mesh unmounted');
if (this.mesh) this.scene.remove(this.mesh); if (this.mesh) this.parent.remove(this.mesh);
if (this.geometry) this.geometry.dispose(); if (this.geometry) this.geometry.dispose();
if (this.material && !this.materialId) this.material.dispose(); if (this.material && !this.materialId) this.material.dispose();
}, },
@ -35,7 +40,7 @@ export default {
} }
this.mesh = new Mesh(this.geometry, this.material); this.mesh = new Mesh(this.geometry, this.material);
this.bindProps(); this.bindProps();
this.scene.add(this.mesh); this.parent.add(this.mesh);
this.$emit('ready'); this.$emit('ready');
}, },
bindProps() { bindProps() {

View File

@ -23,12 +23,13 @@ export default {
}, },
unmounted() { unmounted() {
this.three.offBeforeRender(this.updateCubeRT); this.three.offBeforeRender(this.updateCubeRT);
if (this.cubeCamera) this.parent.remove(this.cubeCamera);
}, },
methods: { methods: {
initMirrorMesh() { initMirrorMesh() {
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
this.scene.add(this.cubeCamera); this.parent.add(this.cubeCamera);
this.material.envMap = cubeRT.texture; this.material.envMap = cubeRT.texture;
this.material.needsUpdate = true; this.material.needsUpdate = true;

View File

@ -25,13 +25,14 @@ export default {
}, },
unmounted() { unmounted() {
this.three.offBeforeRender(this.updateCubeRT); this.three.offBeforeRender(this.updateCubeRT);
if (this.cubeCamera) this.parent.remove(this.cubeCamera);
}, },
methods: { methods: {
initMirrorMesh() { initMirrorMesh() {
const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter });
this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT);
useBindProp(this, 'position', this.cubeCamera.position); useBindProp(this, 'position', this.cubeCamera.position);
this.scene.add(this.cubeCamera); this.parent.add(this.cubeCamera);
this.material.envMap = cubeRT.texture; this.material.envMap = cubeRT.texture;
this.material.refractionRatio = this.refractionRatio; this.material.refractionRatio = this.refractionRatio;

View File

@ -1,4 +1,5 @@
import { Sprite, SpriteMaterial, TextureLoader } from 'three'; import { Sprite, SpriteMaterial, TextureLoader } from 'three';
import { inject } from 'vue';
import useBindProp from '../use/useBindProp.js'; import useBindProp from '../use/useBindProp.js';
export default { export default {
@ -9,6 +10,9 @@ export default {
position: Object, position: Object,
scale: Object, scale: Object,
}, },
created() {
this.parent = inject('group', this.scene);
},
mounted() { mounted() {
this.texture = new TextureLoader().load(this.src, this.onLoaded); this.texture = new TextureLoader().load(this.src, this.onLoaded);
this.material = new SpriteMaterial({ map: this.texture }); this.material = new SpriteMaterial({ map: this.texture });
@ -17,13 +21,13 @@ export default {
useBindProp(this, 'position', this.sprite.position); useBindProp(this, 'position', this.sprite.position);
useBindProp(this, 'scale', this.sprite.scale); useBindProp(this, 'scale', this.sprite.scale);
this.scene.add(this.sprite); this.parent.add(this.sprite);
this.$emit('ready'); this.$emit('ready');
}, },
unmounted() { unmounted() {
this.texture.dispose(); this.texture.dispose();
this.material.dispose(); this.material.dispose();
this.scene.remove(this.sprite); this.parent.remove(this.sprite);
}, },
methods: { methods: {
onLoaded() { onLoaded() {

View File

@ -8,6 +8,7 @@ export const TroisJSVuePlugin = {
'PerspectiveCamera', 'PerspectiveCamera',
'Renderer', 'Renderer',
'Scene', 'Scene',
'Group',
'BoxGeometry', 'BoxGeometry',
'CircleGeometry', 'CircleGeometry',