merge audio columns into 1 buffer geometry and use buffers to scale to audio, only need to create 64 boxes not 256, fix redundant boxes
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
AFRAME.registerComponent('analyser', {
|
||||
dependencies: ['audioanalyser'],
|
||||
schema: {
|
||||
height: {default: 1.0},
|
||||
thickness: {default: 0.1},
|
||||
separation: {default: 0.3},
|
||||
scale: {default: 4.0},
|
||||
mirror: {default: 3}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.analyser = this.el.components.audioanalyser;
|
||||
this.columns = null;
|
||||
var material = this.el.sceneEl.systems.materials.black;
|
||||
var geometry = new THREE.BoxBufferGeometry();
|
||||
for (var i = 0; i < this.analyser.data.fftSize; i++) {
|
||||
for (var side = 0; side < 2; side++) {
|
||||
var column = new THREE.Mesh(geometry, material);
|
||||
this.el.object3D.add(column);
|
||||
}
|
||||
}
|
||||
this.columns = this.el.object3D.children;
|
||||
},
|
||||
|
||||
update: function () {
|
||||
var z = 0;
|
||||
for (var i = 0; i < this.columns.length; i++) {
|
||||
this.columns[i].position.x = ((i % 2) * 2 - 1) * this.data.mirror;
|
||||
this.columns[i].position.z = z;
|
||||
this.columns[i].scale.set(this.data.thickness, this.data.height, this.data.thickness);
|
||||
z -= this.data.separation;
|
||||
}
|
||||
},
|
||||
|
||||
tick: function () {
|
||||
var v;
|
||||
var height = this.data.height;
|
||||
var n = this.columns.length / 2;
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
v = height + this.analyser.levels[i] / 256.0 * this.data.scale;
|
||||
this.columns[i * 2 + 0].scale.y = v;
|
||||
this.columns[i * 2 + 1].scale.y = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
94
src/components/audio-columns.js
Normal file
94
src/components/audio-columns.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 72 values per box.
|
||||
* Divided by 3 (x, y, z) is 24 vertices.
|
||||
* 6 vertices per side of the cube (2 faces per side).
|
||||
*/
|
||||
const NUM_VALUES_PER_BOX = 72;
|
||||
|
||||
/**
|
||||
* Column bars moving in sync to the audio via audio analyser.
|
||||
*/
|
||||
AFRAME.registerComponent('audio-columns', {
|
||||
dependencies: ['audioanalyser'],
|
||||
|
||||
schema: {
|
||||
height: {default: 1.0},
|
||||
mirror: {default: 3},
|
||||
scale: {default: 4.0},
|
||||
separation: {default: 0.3},
|
||||
thickness: {default: 0.1}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.analyser = this.el.components.audioanalyser;
|
||||
|
||||
// Number of levels is half the FFT size.
|
||||
this.frequencyBinCount = this.analyser.data.fftSize / 2;
|
||||
|
||||
// Create boxes (one row on each side per level).
|
||||
const geometries = [];
|
||||
let zPosition = 0;
|
||||
for (let i = 0; i < this.frequencyBinCount; i++) {
|
||||
for (let side = 0; side < 2; side++) {
|
||||
const box = new THREE.BoxBufferGeometry();
|
||||
this.initBox(box, side === 0 ? 1 : -1, zPosition);
|
||||
geometries.push(box);
|
||||
// Move Z back.
|
||||
zPosition -= this.data.separation;
|
||||
}
|
||||
}
|
||||
|
||||
this.geometry = THREE.BufferGeometryUtils.mergeBufferGeometries(geometries)
|
||||
const mesh = new THREE.Mesh(this.geometry, this.el.sceneEl.systems.materials.black);
|
||||
this.el.setObject3D('mesh', mesh);
|
||||
},
|
||||
|
||||
tick: function () {
|
||||
// Step by 2 since we create one box of each side per level.
|
||||
for (let i = 0; i < this.frequencyBinCount * 2; i += 2) {
|
||||
let yScale = (this.data.height / 2) + this.analyser.levels[Math.floor(i / 2)] / 256.0 *
|
||||
this.data.scale;
|
||||
if (isNaN(yScale)) { return; }
|
||||
this.setBoxHeight(i, yScale);
|
||||
this.setBoxHeight(i + 1, yScale);
|
||||
this.geometry.attributes.position.needsUpdate = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize box by changing vertex buffer, to set position and scale.
|
||||
*/
|
||||
initBox: function (box, flip, zPosition) {
|
||||
const data = this.data;
|
||||
|
||||
// Set position and scale of box via vertices.
|
||||
for (let v = 0; v < box.attributes.position.array.length; v += 3) {
|
||||
// Apply thickness to X and Z.
|
||||
box.attributes.position.array[v] *= data.thickness;
|
||||
box.attributes.position.array[v + 2] *= data.thickness;
|
||||
|
||||
// Apply zPosition.
|
||||
box.attributes.position.array[v + 2] += zPosition;
|
||||
|
||||
// Apply height to Y.
|
||||
box.attributes.position.array[v + 1] *= data.height / 2;
|
||||
|
||||
// Change X vertex positions for mirroring.
|
||||
box.attributes.position.array[v] += flip * data.mirror;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set Y of vertices.
|
||||
*/
|
||||
setBoxHeight: function (boxNumber, height) {
|
||||
const boxIndex = boxNumber * NUM_VALUES_PER_BOX;
|
||||
for (let i = boxIndex; i < boxIndex + NUM_VALUES_PER_BOX; i += 3) {
|
||||
// Set Y.
|
||||
let yValue = this.geometry.attributes.position.array[i + 1];
|
||||
this.geometry.attributes.position.array[i + 1] = yValue >= 0
|
||||
? height
|
||||
: -1 * height;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -162,7 +162,7 @@ AFRAME.registerComponent('song-preview-system', {
|
||||
|
||||
updateAnalyser: function () {
|
||||
document.getElementById('introSong').pause();
|
||||
document.getElementById('audioanalyser').setAttribute('audioanalyser', 'src', this.audio);
|
||||
document.getElementById('audioColumns').setAttribute('audioanalyser', 'src', this.audio);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user