UNPKG

aframe-extras

Version:

Add-ons and examples for A-Frame VR.

99 lines (86 loc) 2.71 kB
/** * Flat-shaded ocean primitive. * * Based on a Codrops tutorial: * http://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/ */ 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' } }); 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; const data = this.data; let material = el.components.material; const geometry = new THREE.PlaneGeometry(data.width, data.depth, data.density, data.density); this.waves = []; const posAttribute = geometry.getAttribute('position'); for (let i = 0; i < posAttribute.count; i++) { this.waves.push({ z: posAttribute.getZ(i), 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, flatShading: true, }); } 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 posAttribute = this.mesh.geometry.getAttribute('position'); for (let i = 0; i < posAttribute.count; i++){ const vprops = this.waves[i]; const value = vprops.z + Math.sin(vprops.ang) * vprops.amp; posAttribute.setZ(i, value); vprops.ang += vprops.speed * dt; } posAttribute.needsUpdate = true; } });