Skip to content

Commit 1280c0a

Browse files
author
Sascha Braun
committed
ADD object nesting
ADD fog and group component UPDATE texture component: add src prop
1 parent 01b4394 commit 1280c0a

17 files changed

+284
-70
lines changed

src/views/About.vue

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
<geometry name="plane" :factory="planeFactory"/>
2222
</template>
2323

24+
<fog exp2/>
25+
2426
<camera name="mainCamera" :factory="cameraFactory">
2527
<position :value="scene1.camera.position"/>
2628
<rotation :value="scene1.camera.rotation" rad/>
@@ -33,21 +35,26 @@
3335
<shadows cast/>
3436
</light>
3537

36-
<mesh name="waterPlane" geometry="plane" material="waterMat">
37-
<rotation :value="{ x: -90, y: 0, z: 0 }"/>
38-
<shadows receive/>
39-
</mesh>
40-
41-
<mesh v-for="field in scene1.fields"
42-
:key="field.id"
43-
:name="'field-'+field.id"
44-
geometry="cube"
45-
material="cubeMat"
46-
>
47-
<position :value="{ x: field.x * 2, y: 0, z: field.y * 2}"/>
48-
<scale :value="{ x: 1.2, y: 0.7, z: 1.2}"/>
49-
<shadows cast receive/>
50-
</mesh>
38+
<group name="group">
39+
<position :value="{ x: 0, y: 0, z: 0 }"/>
40+
41+
<mesh name="waterPlane" geometry="plane" material="waterMat">
42+
<rotation :value="{ x: -90, y: 0, z: 0 }"/>
43+
<shadows receive/>
44+
</mesh>
45+
46+
<mesh v-for="field in scene1.fields"
47+
:key="field.id"
48+
:name="'field-'+field.id"
49+
geometry="cube"
50+
material="cubeMat"
51+
>
52+
<position :value="{ x: field.x * 2, y: 0, z: field.y * 2}"/>
53+
<scale :value="{ x: 1.2, y: 0.7, z: 1.2}"/>
54+
<shadows cast receive/>
55+
</mesh>
56+
</group>
57+
5158
</scene>
5259

5360
<scene :name="scene2.name" :active.sync="scene2.active">

src/vue-three/components/Fog.tsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import * as THREE from "three";
2+
import { Component, Mixins, Prop, Provide, Watch } from "vue-property-decorator";
3+
4+
import { ThreeComponent, ThreeSceneComponent } from "./base";
5+
6+
@Component
7+
export class Fog extends Mixins(ThreeComponent, ThreeSceneComponent) {
8+
@Prop({ type: Number, default: 0xffffff })
9+
public color!: number;
10+
11+
@Prop({ type: Number, default: 1 })
12+
public near!: number;
13+
14+
@Prop({ type: Number, default: 1000 })
15+
public far!: number;
16+
17+
@Prop({ type: Boolean, default: false })
18+
public exp2!: boolean;
19+
20+
@Prop({ type: Number, default: 0.005 })
21+
public density!: number;
22+
23+
@Watch("color")
24+
public watchColor() {
25+
this.m_color.set(this.color);
26+
this.m_fog.color.set(this.color);
27+
}
28+
@Watch("exp2")
29+
public watchExp() {
30+
if (this.exp2) {
31+
this.m_fog = new THREE.FogExp2(this.color, this.density);
32+
} else {
33+
this.m_fog = new THREE.Fog(this.color, this.near, this.far);
34+
}
35+
this.scene().fog = this.m_fog;
36+
}
37+
@Watch("near")
38+
public watchNear() {
39+
if (this.m_fog instanceof THREE.Fog) {
40+
this.m_fog.near = this.near;
41+
}
42+
}
43+
@Watch("near")
44+
public watchFar() {
45+
if (this.m_fog instanceof THREE.Fog) {
46+
this.m_fog.far = this.far;
47+
}
48+
}
49+
@Watch("density")
50+
public watchDensity() {
51+
if (this.m_fog instanceof THREE.FogExp2) {
52+
this.m_fog.density = this.density;
53+
}
54+
}
55+
56+
private m_color!: THREE.Color;
57+
private m_fog!: THREE.IFog;
58+
private m_created = false;
59+
60+
public async created() {
61+
if (!this.scene) {
62+
throw new Error(
63+
"Fog component can only be added as a child to a scene component"
64+
);
65+
}
66+
67+
this.m_color = new THREE.Color(this.color);
68+
if (this.exp2) {
69+
this.m_fog = new THREE.FogExp2(this.color, this.density);
70+
} else {
71+
this.m_fog = new THREE.Fog(this.color, this.near, this.far);
72+
}
73+
const scene = this.scene();
74+
scene.background = this.m_color;
75+
scene.fog = this.m_fog;
76+
77+
this.m_created = true;
78+
}
79+
80+
public beforeDestroy() {
81+
console.log("fog beforeDestroy");
82+
const scene = this.scene();
83+
scene.fog = null;
84+
}
85+
86+
public render(h: any) {
87+
if (!this.m_created) {
88+
return null;
89+
}
90+
return (
91+
<div className="fog">
92+
<span>Fog</span>
93+
</div>
94+
);
95+
}
96+
}

src/vue-three/components/Geometry.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ export class Geometry extends Mixins(ThreeComponent, ThreeAssetComponent) {
1111
@Prop({ required: true, type: Function })
1212
public factory!: GeometryFactory;
1313

14-
public async mounted() {
15-
console.log("mounted geometry", this.name);
14+
public async created() {
15+
console.log("created geometry", this.name);
1616
this.asset = this.factory();
1717
this.app().assets.add(this.name, AssetTypes.GEOMETRY, this.asset);
1818
}

src/vue-three/components/Group.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as THREE from "three";
2+
import { Component, Mixins, Prop, Provide } from "vue-property-decorator";
3+
4+
import { ThreeComponent, ThreeObjectComponent, ThreeSceneComponent } from "./base";
5+
6+
@Component
7+
export class Group extends Mixins(
8+
ThreeComponent,
9+
ThreeSceneComponent,
10+
ThreeObjectComponent
11+
) {
12+
@Prop({ required: true })
13+
private name!: string;
14+
15+
@Provide("object")
16+
public provideObject = this.getObject;
17+
18+
private m_group!: THREE.Group;
19+
private m_created = false;
20+
21+
public getObject(): THREE.Object3D {
22+
return this.m_group;
23+
}
24+
25+
public async created() {
26+
if (!this.scene && !this.object) {
27+
throw new Error(
28+
"Group component can only be added as child to an object or scene component"
29+
);
30+
}
31+
32+
this.m_group = new THREE.Group();
33+
const parent = this.object ? this.object() : this.scene();
34+
parent.add(this.m_group);
35+
36+
this.m_created = true;
37+
}
38+
39+
public beforeDestroy() {
40+
console.log("group beforeDestroy");
41+
const parent = this.object ? this.object() : this.scene();
42+
parent.remove(this.m_group);
43+
}
44+
45+
public render(h: any) {
46+
if (!this.m_created) {
47+
return null;
48+
}
49+
return (
50+
<div className="group">
51+
<span>Group {this.name}</span>
52+
<ul>{this.$slots.default}</ul>
53+
</div>
54+
);
55+
}
56+
}

src/vue-three/components/Light.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,48 @@ import * as THREE from "three";
22
import { Component, Mixins, Prop, Provide, Watch } from "vue-property-decorator";
33

44
import { LightFactory } from "../types";
5-
import { ThreeComponent, ThreeSceneComponent } from "./base";
5+
import { ThreeComponent, ThreeObjectComponent, ThreeSceneComponent } from "./base";
66

77
@Component
8-
export class Light extends Mixins(ThreeComponent, ThreeSceneComponent) {
8+
export class Light extends Mixins(
9+
ThreeComponent,
10+
ThreeSceneComponent,
11+
ThreeObjectComponent
12+
) {
913
@Prop({ required: true })
1014
private name!: string;
1115

12-
@Prop({ default: false, type: Boolean })
13-
private castShadow!: boolean;
14-
1516
@Prop({ required: true, type: Function })
1617
public factory!: LightFactory;
1718

1819
@Provide("object")
19-
public provideObject = this.object;
20+
public provideObject = this.getObject;
2021

2122
private m_light!: THREE.Light;
2223
private m_created = false;
2324

24-
@Watch("castShadow")
25-
private onChangeCastShadow() {
26-
this.m_light.castShadow = this.castShadow;
27-
}
28-
29-
public object(): THREE.Object3D {
25+
public getObject(): THREE.Object3D {
3026
return this.m_light;
3127
}
3228

3329
public async created() {
30+
if (!this.scene && !this.object) {
31+
throw new Error(
32+
"Light component can only be added as child to an object or scene component"
33+
);
34+
}
35+
3436
this.m_light = await this.factory();
35-
this.onChangeCastShadow();
36-
this.scene().add(this.m_light);
37+
const parent = this.object ? this.object() : this.scene();
38+
parent.add(this.m_light);
39+
3740
this.m_created = true;
3841
}
3942

4043
public beforeDestroy() {
4144
console.log("light beforeDestroy");
42-
if (this.scene()) {
43-
console.log("light remove from scene");
44-
this.scene().remove(this.m_light);
45-
}
45+
const parent = this.object ? this.object() : this.scene();
46+
parent.remove(this.m_light);
4647
}
4748

4849
public render(h: any) {

src/vue-three/components/Material.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ export class Material extends Mixins(ThreeComponent, ThreeAssetComponent) {
1111
@Prop({ required: true, type: Function })
1212
private factory!: MaterialFactory;
1313

14-
public mounted() {
15-
console.log("mounted material", this.name);
14+
public created() {
15+
console.log("created material", this.name);
1616
this.asset = this.factory();
1717
this.app().assets.add(this.name, AssetTypes.MATERIAL, this.asset);
1818
}

src/vue-three/components/Mesh.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import { Component, Mixins, Prop, Provide } from "vue-property-decorator";
33

44
import { AssetTypes, GeometryType, MaterialType } from "@/vue-three/types";
55

6-
import { ThreeComponent, ThreeSceneComponent } from "./base";
6+
import { ThreeComponent, ThreeObjectComponent, ThreeSceneComponent } from "./base";
77

88
@Component
9-
export class Mesh extends Mixins(ThreeComponent, ThreeSceneComponent) {
9+
export class Mesh extends Mixins(
10+
ThreeComponent,
11+
ThreeSceneComponent,
12+
ThreeObjectComponent
13+
) {
1014
@Prop({ required: true, type: String })
1115
private name!: string;
1216

@@ -17,16 +21,22 @@ export class Mesh extends Mixins(ThreeComponent, ThreeSceneComponent) {
1721
private geometry!: string;
1822

1923
@Provide("object")
20-
private provideObject = this.object;
24+
private provideObject = this.getObject;
2125

2226
private m_mesh!: THREE.Mesh;
2327
private m_created = false;
2428

25-
public object(): THREE.Object3D {
29+
public getObject(): THREE.Object3D {
2630
return this.m_mesh;
2731
}
2832

2933
public async created() {
34+
if (!this.scene && !this.object) {
35+
throw new Error(
36+
"Mesh component can only be added as child to an object or mesh component"
37+
);
38+
}
39+
3040
const materialProm = this.app().assets.get(
3141
this.material,
3242
AssetTypes.MATERIAL
@@ -59,17 +69,17 @@ export class Mesh extends Mixins(ThreeComponent, ThreeSceneComponent) {
5969
geometry as GeometryType,
6070
material as MaterialType
6171
);
62-
this.scene().add(this.m_mesh);
72+
73+
const parent = this.object ? this.object() : this.scene();
74+
parent.add(this.m_mesh);
6375

6476
this.m_created = true;
6577
}
6678

6779
public beforeDestroy() {
6880
console.log("mesh beforeDestroy");
69-
if (this.scene()) {
70-
console.log("mesh remove from scene");
71-
this.scene().remove(this.m_mesh);
72-
}
81+
const parent = this.object ? this.object() : this.scene();
82+
parent.remove(this.m_mesh);
7383
}
7484

7585
public render(h: any) {

src/vue-three/components/Scene.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ export class Scene extends Mixins(ThreeComponent) {
1313
public active!: boolean;
1414

1515
@Provide("scene")
16-
public provideScene = this.scene;
16+
public provideScene = this.getScene;
1717

1818
private m_isReady = false;
1919
private m_isActive = false;
2020
private m_scene?: THREE.Scene;
2121

22-
public scene() {
22+
public getScene() {
2323
return this.m_scene;
2424
}
2525

@@ -43,15 +43,18 @@ export class Scene extends Mixins(ThreeComponent) {
4343
}
4444
}
4545

46-
public onDeactivate() {
46+
public async onDeactivate() {
4747
console.log("deactivate scene", this.name);
4848

4949
const manager = this.app().sceneManager;
5050
if (this.m_scene === manager.active) {
5151
manager.active = undefined;
5252
}
53-
this.m_scene = undefined;
5453
this.m_isReady = false;
54+
55+
await Vue.nextTick();
56+
57+
this.m_scene = undefined;
5558
}
5659

5760
public async onActivate() {

0 commit comments

Comments
 (0)