Skip to content

Commit bae3513

Browse files
author
Sascha Braun
committed
add better three object properties handling (defined now in separate components instead of props)
1 parent ed39e6e commit bae3513

File tree

12 files changed

+292
-156
lines changed

12 files changed

+292
-156
lines changed

src/views/About.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Component, Vue } from "vue-property-decorator";
33

44
import { components, GeometryFactory, LightFactory, MaterialFactory } from "@/vue-three";
55

6+
console.log(components);
7+
68
@Component({
79
components: {
810
...components

src/views/About.vue

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,30 @@
2121
<geometry name="plane" :factory="planeFactory"/>
2222
</template>
2323

24-
<camera name="mainCamera" :position="{x: 0, y: 10, z: 0}"/>
25-
<light name="light" :factory="lightFactory" castShadow :position="{x: 0, y: 10, z: 0}"/>
26-
<mesh name="waterPlane" receiveShadow geometry="plane" material="waterMat" :rotation="{ x: -90, y: 0, z: 0 }"/>
24+
<camera name="mainCamera">
25+
<position :value="{x: 0, y: 10, z: 0}"/>
26+
</camera>
27+
28+
<light name="light" :factory="lightFactory">
29+
<position :value="{x: 0, y: 10, z: 0}"/>
30+
<shadows cast/>
31+
</light>
32+
33+
<mesh name="waterPlane" geometry="plane" material="waterMat">
34+
<rotation :value="{ x: -90, y: 0, z: 0 }"/>
35+
<shadows receive/>
36+
</mesh>
2737

2838
<mesh v-for="(field, index) in scene1.fields"
2939
:key="field.x + ' ' + field.y"
3040
:name="'field-'+index"
31-
castShadow
32-
receiveShadow
3341
geometry="cube"
3442
material="cubeMat"
35-
:position="{ x: field.x * 2, y: 0, z: field.y * 2}"
36-
/>
43+
>
44+
<position :value="{ x: field.x * 2, y: 0, z: field.y * 2}"/>
45+
<scale :value="{ x: 1.2, y: 0.7, z: 1.2}"/>
46+
<shadows cast receive/>
47+
</mesh>
3748
</scene>
3849

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

src/vue-three/components/Camera.tsx

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as THREE from "three";
2-
import { Component, Inject, Prop, Vue, Watch } from "vue-property-decorator";
2+
import { Component, Inject, Prop, Provide, Vue, Watch } from "vue-property-decorator";
33

44
import { ThreeApplication } from "../core";
55
import { OrbitControls } from "../core/OrbitCamera";
@@ -15,49 +15,15 @@ export class Camera extends Vue {
1515
@Prop({ default: true, type: Boolean })
1616
private main!: boolean;
1717

18-
@Prop({
19-
default() {
20-
return {
21-
x: 0,
22-
y: 0,
23-
z: 0
24-
};
25-
}
26-
})
27-
private position!: { x: number; y: number; z: number };
28-
29-
@Prop({
30-
default() {
31-
return {
32-
x: 0,
33-
y: 0,
34-
z: 0
35-
};
36-
}
37-
})
38-
private rotation!: { x: number; y: number; z: number };
18+
@Provide("object")
19+
public provideObject = this.object;
3920

4021
private m_isMain = false;
41-
private m_camera!: THREE.Camera;
22+
private m_camera!: THREE.PerspectiveCamera;
4223
private m_controls?: OrbitControls;
4324

44-
@Watch("position", { deep: true })
45-
private onChangePosition() {
46-
this.m_camera.position.set(
47-
this.position.x,
48-
this.position.y,
49-
this.position.z
50-
);
51-
}
52-
53-
@Watch("rotation", { deep: true })
54-
private onChangeRotation() {
55-
const rad = THREE.Math.degToRad;
56-
this.m_camera.rotation.set(
57-
rad(this.rotation.x),
58-
rad(this.rotation.y),
59-
rad(this.rotation.z)
60-
);
25+
public object(): THREE.Object3D {
26+
return this.m_camera;
6127
}
6228

6329
@Watch("main")
@@ -96,7 +62,8 @@ export class Camera extends Vue {
9662
manager.main = this.m_camera;
9763
}
9864

99-
public mounted() {
65+
public created() {
66+
console.log("camera created");
10067
const { width, height } = this.app().renderer.getSize();
10168
const viewAngle = 60;
10269
const nearClipping = 0.1;
@@ -109,8 +76,6 @@ export class Camera extends Vue {
10976
farClipping
11077
);
11178

112-
this.onChangePosition();
113-
this.onChangeRotation();
11479
this.m_controls = new OrbitControls(
11580
this.m_camera,
11681
this.app().renderer.domElement
@@ -119,6 +84,10 @@ export class Camera extends Vue {
11984
this.onChangeMain();
12085
}
12186

87+
public mounted() {
88+
console.log("camera mounted");
89+
}
90+
12291
public beforeDestroy() {
12392
this.onDeactivate();
12493
if (this.m_camera && this.m_controls) {
@@ -131,6 +100,11 @@ export class Camera extends Vue {
131100
if (!this.main) {
132101
return null;
133102
}
134-
return <div className="camera">Camera</div>;
103+
return (
104+
<div className="camera">
105+
<span>Camera</span>
106+
<ul>{this.$slots.default}</ul>
107+
</div>
108+
);
135109
}
136110
}

src/vue-three/components/Light.tsx

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as THREE from "three";
2-
import { Component, Inject, Prop, Vue, Watch } from "vue-property-decorator";
2+
import { Component, Inject, Prop, Provide, Vue, Watch } from "vue-property-decorator";
33

44
import { ThreeApplication } from "../core";
55
import { LightFactory } from "../types";
@@ -18,65 +18,29 @@ export class Light extends Vue {
1818
@Prop({ default: false, type: Boolean })
1919
private castShadow!: boolean;
2020

21-
@Prop({
22-
default() {
23-
return {
24-
x: 0,
25-
y: 0,
26-
z: 0
27-
};
28-
}
29-
})
30-
private position!: { x: number; y: number; z: number };
31-
32-
@Prop({
33-
default() {
34-
return {
35-
x: 0,
36-
y: 0,
37-
z: 0
38-
};
39-
}
40-
})
41-
private rotation!: { x: number; y: number; z: number };
42-
4321
@Prop({ required: true, type: Function })
4422
public factory!: LightFactory;
4523

46-
private m_light!: THREE.Light;
47-
48-
@Watch("position", { deep: true })
49-
private onChangePosition() {
50-
this.m_light.position.set(
51-
this.position.x,
52-
this.position.y,
53-
this.position.z
54-
);
55-
}
24+
@Provide("object")
25+
public provideObject = this.object;
5626

57-
@Watch("rotation", { deep: true })
58-
private onChangeRotation() {
59-
const rad = THREE.Math.degToRad;
60-
this.m_light.rotation.set(
61-
rad(this.rotation.x),
62-
rad(this.rotation.y),
63-
rad(this.rotation.z)
64-
);
65-
}
27+
private m_light!: THREE.Light;
28+
private m_created = false;
6629

6730
@Watch("castShadow")
6831
private onChangeCastShadow() {
6932
this.m_light.castShadow = this.castShadow;
7033
}
7134

72-
public async mounted() {
73-
this.m_light = await this.factory();
35+
public object(): THREE.Object3D {
36+
return this.m_light;
37+
}
7438

75-
console.log("light mounted", this.name, this.m_light);
76-
this.onChangePosition();
77-
this.onChangeRotation();
39+
public async created() {
40+
this.m_light = await this.factory();
7841
this.onChangeCastShadow();
7942
this.scene().add(this.m_light);
43+
this.m_created = true;
8044
}
8145

8246
public beforeDestroy() {
@@ -88,6 +52,14 @@ export class Light extends Vue {
8852
}
8953

9054
public render(h: any) {
91-
return <div className="light">Light {this.name}</div>;
55+
if (!this.m_created) {
56+
return null;
57+
}
58+
return (
59+
<div className="light">
60+
<span>Light {this.name}</span>
61+
<ul>{this.$slots.default}</ul>
62+
</div>
63+
);
9264
}
9365
}

src/vue-three/components/Mesh.tsx

Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as THREE from "three";
2-
import { Component, Inject, Prop, Vue, Watch } from "vue-property-decorator";
2+
import { Component, Inject, Prop, Provide, Vue, Watch } from "vue-property-decorator";
33

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

@@ -22,62 +22,17 @@ export class Mesh extends Vue {
2222
@Prop({ required: true, type: String })
2323
private geometry!: string;
2424

25-
@Prop({
26-
default() {
27-
return {
28-
x: 0,
29-
y: 0,
30-
z: 0
31-
};
32-
}
33-
})
34-
private position!: { x: number; y: number; z: number };
35-
36-
@Prop({
37-
default() {
38-
return {
39-
x: 0,
40-
y: 0,
41-
z: 0
42-
};
43-
}
44-
})
45-
private rotation!: { x: number; y: number; z: number };
46-
47-
@Prop({ default: false, type: Boolean })
48-
private receiveShadow!: boolean;
49-
50-
@Prop({ default: false, type: Boolean })
51-
private castShadow!: boolean;
25+
@Provide("object")
26+
private provideObject = this.object;
5227

5328
private m_mesh!: THREE.Mesh;
29+
private m_created = false;
5430

55-
@Watch("receiveShadow")
56-
private onChangeReceiveShadow() {
57-
this.m_mesh.receiveShadow = this.receiveShadow;
58-
}
59-
60-
@Watch("castShadow")
61-
private onChangeCastShadow() {
62-
this.m_mesh.castShadow = this.castShadow;
63-
}
64-
65-
@Watch("position", { deep: true })
66-
private onChangePosition() {
67-
this.m_mesh.position.set(this.position.x, this.position.y, this.position.z);
68-
}
69-
70-
@Watch("rotation", { deep: true })
71-
private onChangeRotation() {
72-
const rad = THREE.Math.degToRad;
73-
this.m_mesh.rotation.set(
74-
rad(this.rotation.x),
75-
rad(this.rotation.y),
76-
rad(this.rotation.z)
77-
);
31+
public object(): THREE.Object3D {
32+
return this.m_mesh;
7833
}
7934

80-
public async mounted() {
35+
public async created() {
8136
const materialProm = this.app().assets.get(
8237
this.material,
8338
AssetTypes.MATERIAL
@@ -110,11 +65,9 @@ export class Mesh extends Vue {
11065
geometry as GeometryType,
11166
material as MaterialType
11267
);
113-
this.onChangePosition();
114-
this.onChangeRotation();
115-
this.onChangeReceiveShadow();
116-
this.onChangeCastShadow();
11768
this.scene().add(this.m_mesh);
69+
70+
this.m_created = true;
11871
}
11972

12073
public beforeDestroy() {
@@ -126,6 +79,14 @@ export class Mesh extends Vue {
12679
}
12780

12881
public render(h: any) {
129-
return <div className="mesh">Mesh {this.name}</div>;
82+
if (!this.m_created) {
83+
return null;
84+
}
85+
return (
86+
<div className="mesh">
87+
<span>Mesh {this.name}</span>
88+
<ul>{this.$slots.default}</ul>
89+
</div>
90+
);
13091
}
13192
}

src/vue-three/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ export * from "./Scene";
66
export * from "./Three";
77
export * from "./Camera";
88
export * from "./Light";
9+
10+
export * from "./properties";
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as THREE from "three";
2+
import { Component, Inject, Prop, Vue, Watch } from "vue-property-decorator";
3+
4+
@Component
5+
export class Position extends Vue {
6+
@Inject()
7+
protected object!: () => THREE.Object3D;
8+
9+
@Prop({
10+
default() {
11+
return {
12+
x: 0,
13+
y: 0,
14+
z: 0
15+
};
16+
}
17+
})
18+
private value!: { x: number; y: number; z: number };
19+
20+
@Watch("value", { deep: true })
21+
private onChange() {
22+
this.object().position.set(this.value.x, this.value.y, this.value.z);
23+
}
24+
25+
public created() {
26+
this.onChange();
27+
}
28+
29+
public render(h: any) {
30+
const valueStringify = `[${this.value.x}, ${this.value.y}, ${
31+
this.value.z
32+
}]`;
33+
return <li>Position {valueStringify}</li>;
34+
}
35+
}

0 commit comments

Comments
 (0)