forked from c-frame/aframe-extras
-
Notifications
You must be signed in to change notification settings - Fork 0
/
a-ocean.js
98 lines (86 loc) · 2.66 KB
/
a-ocean.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
* Flat-shaded ocean primitive.
*
* Based on a Codrops tutorial:
* http://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/
*/
module.exports.Primitive = AFRAME.registerPrimitive('a-ocean', {
defaultComponents: {
ocean: {},
rotation: {x: -90, y: 0, z: 0}
},
mappings: {
width: 'ocean.width',
depth: 'ocean.depth',
density: 'ocean.density',
amplitude: 'ocean.amplitude',
amplitudeVariance: 'ocean.amplitudeVariance',
speed: 'ocean.speed',
speedVariance: 'ocean.speedVariance',
color: 'ocean.color',
opacity: 'ocean.opacity'
}
});
module.exports.Component = AFRAME.registerComponent('ocean', {
schema: {
// Dimensions of the ocean area.
width: {default: 10, min: 0},
depth: {default: 10, min: 0},
// Density of waves.
density: {default: 10},
// Wave amplitude and variance.
amplitude: {default: 0.1},
amplitudeVariance: {default: 0.3},
// Wave speed and variance.
speed: {default: 1},
speedVariance: {default: 2},
// Material.
color: {default: '#7AD2F7', type: 'color'},
opacity: {default: 0.8}
},
/**
* Use play() instead of init(), because component mappings – unavailable as dependencies – are
* not guaranteed to have parsed when this component is initialized.
*/
play: function () {
const el = this.el,
data = this.data;
let material = el.components.material;
const geometry = new THREE.PlaneGeometry(data.width, data.depth, data.density, data.density);
geometry.mergeVertices();
this.waves = [];
for (let v, i = 0, l = geometry.vertices.length; i < l; i++) {
v = geometry.vertices[i];
this.waves.push({
z: v.z,
ang: Math.random() * Math.PI * 2,
amp: data.amplitude + Math.random() * data.amplitudeVariance,
speed: (data.speed + Math.random() * data.speedVariance) / 1000 // radians / frame
});
}
if (!material) {
material = {};
material.material = new THREE.MeshPhongMaterial({
color: data.color,
transparent: data.opacity < 1,
opacity: data.opacity,
shading: THREE.FlatShading,
});
}
this.mesh = new THREE.Mesh(geometry, material.material);
el.setObject3D('mesh', this.mesh);
},
remove: function () {
this.el.removeObject3D('mesh');
},
tick: function (t, dt) {
if (!dt) return;
const verts = this.mesh.geometry.vertices;
for (let v, vprops, i = 0; (v = verts[i]); i++){
vprops = this.waves[i];
v.z = vprops.z + Math.sin(vprops.ang) * vprops.amp;
vprops.ang += vprops.speed * dt;
}
this.mesh.geometry.verticesNeedUpdate = true;
}
});