Files
junisaber/src/components/trail.js

337 lines
11 KiB
JavaScript

AFRAME.registerComponent('trail', {
schema: {
color: {type: 'color'},
enabled: {default: false},
hand: {type: 'string'}
},
init: function () {
var geometry = this.geometry = new THREE.BufferGeometry();
var steps = 10;
var maxPoints = this.maxPoints = 12;
var vertices = this.vertices = new Float32Array(36 * maxPoints);
var colors = this.colors = new Float32Array(48 * maxPoints);
var bladeColor = this.bladeColor = new THREE.Color(this.data.color);
this.bladeColor = {
red: bladeColor.r,
green: bladeColor.g,
blue: bladeColor.b,
alpha: 1.0
};
this.saberEl = this.el.querySelector('.blade');
this.layers = 0;
this.saberTrajectory = [
{top: new THREE.Vector3(-0.5, 0, 0), center: new THREE.Vector3(0, 0, 0), bottom: new THREE.Vector3(0.5, 0, 0)},
{top: new THREE.Vector3(-0.5, 0.5, 0), center: new THREE.Vector3(0, 0.5, 0), bottom: new THREE.Vector3(0.5, 0.5, 0)},
{top: new THREE.Vector3(-0.5, 1.0, 0), center: new THREE.Vector3(0, 1.0, 0), bottom: new THREE.Vector3(0.5, 1.0, 0)}
];
//geometry.setDrawRange(0, 0);
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3).setDynamic(true));
geometry.addAttribute('vertexColor', new THREE.BufferAttribute(colors, 4).setDynamic(true));
var material = new THREE.ShaderMaterial({
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors,
transparent: true,
vertexShader: [
'varying vec4 vColor;',
'attribute vec4 vertexColor;',
'void main() {',
'vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);',
'vColor = vertexColor;',
'gl_Position = projectionMatrix * modelViewPosition;',
'}'
].join(''),
fragmentShader: [
'varying vec4 vColor;',
'void main() {',
'gl_FragColor = vColor;',
'}'
].join('')
});
//this.initGeometry();
var mesh = this.mesh = new THREE.Mesh(geometry, material);
// var material = new THREE.MeshBasicMaterial({color: 0xffff00});
// var wireframe = new THREE.WireframeGeometry(geometry);
// var mesh = new THREE.LineSegments(wireframe, material);
mesh.frustumCulled = false;
mesh.vertices = vertices;
//mesh.scale.set(0.4, 0.4, 0.4);
//mesh.rotation.set(0, 0, Math.PI / 2.0);
this.el.sceneEl.setObject3D(`trail__${this.data.hand}`, mesh);
},
addLayer: function (length) {
var startX = -1.0;
var segments = this.segments;
var dx = 2 / segments;
var colors = this.colors;
var bottomLayer;
var vertices = this.vertices;
var uvs = this.uvs;
var indexOffset;
var color = this.bladeColor;
if (this.layers >= this.maxLayers) { this.layers = 0; }
bottomLayer = this.layers * length;
length = bottomLayer + length;
indexOffset = this.layers * segments * 18;
colorOffset = this.layers * segments * 24;
for (var i = 0; i < segments; ++i) {
vertices[indexOffset + 18 * i] = startX + i * dx;
vertices[indexOffset + 18 * i + 1] = bottomLayer;
vertices[indexOffset + 18 * i + 2] = 0.0;
// Color
colors[colorOffset + 24 * i] = color.red;
colors[colorOffset + 24 * i + 1] = color.green;
colors[colorOffset + 24 * i + 2] = color.blue;
colors[colorOffset + 24 * i + 3] = color.alpha;
vertices[indexOffset + 18 * i + 3] = startX + i * dx;
vertices[indexOffset + 18 * i + 4] = length;
vertices[indexOffset + 18 * i + 5] = 0.0;
// Color
colors[colorOffset + 24 * i + 4] = color.red;
colors[colorOffset + 24 * i + 5] = color.green;
colors[colorOffset + 24 * i + 6] = color.blue;
colors[colorOffset + 24 * i + 7] = color.alpha;
vertices[indexOffset + 18 * i + 6] = startX + i * dx + dx;
vertices[indexOffset + 18 * i + 7] = length;
vertices[indexOffset + 18 * i + 8] = 0.0;
// Color
colors[colorOffset + 24 * i + 8] = color.red;
colors[colorOffset + 24 * i + 9] = color.green;
colors[colorOffset + 24 * i + 10] = color.blue;
colors[colorOffset + 24 * i + 11] = color.alpha;
vertices[indexOffset + 18 * i + 9] = startX + i * dx + dx;
vertices[indexOffset + 18 * i + 10] = bottomLayer;
vertices[indexOffset + 18 * i + 11] = 0.0;
// Color
colors[colorOffset + 24 * i + 12] = color.red;
colors[colorOffset + 24 * i + 13] = color.green;
colors[colorOffset + 24 * i + 14] = color.blue;
colors[colorOffset + 24 * i + 15] = color.alpha;
vertices[indexOffset + 18 * i + 12] = startX + i * dx;
vertices[indexOffset + 18 * i + 13] = bottomLayer;
vertices[indexOffset + 18 * i + 14] = 0.0;
// Color
colors[colorOffset + 24 * i + 16] = color.red;
colors[colorOffset + 24 * i + 17] = color.green;
colors[colorOffset + 24 * i + 18] = color.blue;
colors[colorOffset + 24 * i + 19] = color.alpha;
vertices[indexOffset + 18 * i + 15] = startX + i * dx + dx;
vertices[indexOffset + 18 * i + 16] = length;
vertices[indexOffset + 18 * i + 17] = 0.0;
// Color
colors[colorOffset + 24 * i + 20] = color.red;
colors[colorOffset + 24 * i + 21] = color.green;
colors[colorOffset + 24 * i + 22] = color.blue;
colors[colorOffset + 24 * i + 23] = color.alpha;
}
this.layers++;
this.geometry.attributes.position.needsUpdate = true;
this.geometry.attributes.vertexColor.needsUpdate = true;
this.geometry.attributes.uv.needsUpdate = true;
},
initGeometry: function () {
var i;
var previousPoint;
var currentPoint;
var saberTrajectory = this.saberTrajectory;
var vertices = this.geometry.attributes.position.array;
var colors = this.geometry.attributes.vertexColor.array;
var color = this.bladeColor;
var alpha;
var previousAlpha;
for (i = 1; i < saberTrajectory.length; i++) {
if (i === 1) { previousAlpha = alpha; }
alpha = 1.0 - ((saberTrajectory.length - i) / saberTrajectory.length);
currentPoint = saberTrajectory[i];
previousPoint = saberTrajectory[i-1];
vertices[36 * i] = previousPoint.center.x;
vertices[36 * i + 1] = previousPoint.center.y;
vertices[36 * i + 2] = previousPoint.center.z;
// Color
colors[48 * i] = color.red;
colors[48 * i + 1] = color.green;
colors[48 * i + 2] = color.blue;
colors[48 * i + 3] = previousAlpha * 0.2;
vertices[36 * i + 3] = currentPoint.top.x;
vertices[36 * i + 4] = currentPoint.top.y;
vertices[36 * i + 5] = currentPoint.top.z;
// Color
colors[48 * i + 4] = color.red;
colors[48 * i + 5] = color.green;
colors[48 * i + 6] = color.blue;
colors[48 * i + 7] = alpha;
vertices[36 * i + 6] = previousPoint.top.x;
vertices[36 * i + 7] = previousPoint.top.y;
vertices[36 * i + 8] = previousPoint.top.z;
// Color
colors[48 * i + 8] = color.red;
colors[48 * i + 9] = color.green;
colors[48 * i + 10] = color.blue;
colors[48 * i + 11] = previousAlpha;
vertices[36 * i + 9] = previousPoint.center.x;
vertices[36 * i + 10] = previousPoint.center.y;
vertices[36 * i + 11] = previousPoint.center.z;
// Color
colors[48 * i + 12] = color.red;
colors[48 * i + 13] = color.green;
colors[48 * i + 14] = color.blue;
colors[48 * i + 15] = previousAlpha * 0.2;
vertices[36 * i + 12] = currentPoint.center.x;
vertices[36 * i + 13] = currentPoint.center.y;
vertices[36 * i + 14] = currentPoint.center.z;
// Color
colors[48 * i + 16] = color.red;
colors[48 * i + 17] = color.green;
colors[48 * i + 18] = color.blue;
colors[48 * i + 19] = alpha * 0.2;
vertices[36 * i + 15] = currentPoint.top.x;
vertices[36 * i + 16] = currentPoint.top.y;
vertices[36 * i + 17] = currentPoint.top.z;
// Color
colors[48 * i + 20] = color.red;
colors[48 * i + 21] = color.green;
colors[48 * i + 22] = color.blue;
colors[48 * i + 23] = alpha;
vertices[36 * i + 18] = previousPoint.bottom.x;
vertices[36 * i + 19] = previousPoint.bottom.y;
vertices[36 * i + 20] = previousPoint.bottom.z;
// Color
colors[48 * i + 24] = color.red;
colors[48 * i + 25] = color.green;
colors[48 * i + 26] = color.blue;
colors[48 * i + 27] = 0.0;
vertices[36 * i + 21] = currentPoint.center.x;
vertices[36 * i + 22] = currentPoint.center.y;
vertices[36 * i + 23] = currentPoint.center.z;
// Color
colors[48 * i + 28] = color.red;
colors[48 * i + 29] = color.green;
colors[48 * i + 30] = color.blue;
colors[48 * i + 31] = alpha * 0.2;
vertices[36 * i + 24] = previousPoint.center.x;
vertices[36 * i + 25] = previousPoint.center.y;
vertices[36 * i + 26] = previousPoint.center.z;
// Color
colors[48 * i + 32] = color.red;
colors[48 * i + 33] = color.green;
colors[48 * i + 34] = color.blue;
colors[48 * i + 35] = previousAlpha * 0.2;
vertices[36 * i + 27] = previousPoint.bottom.x;
vertices[36 * i + 28] = previousPoint.bottom.y;
vertices[36 * i + 29] = previousPoint.bottom.z;
// Color
colors[48 * i + 36] = color.red;
colors[48 * i + 37] = color.green;
colors[48 * i + 38] = color.blue;
colors[48 * i + 39] = 0.0;
vertices[36 * i + 30] = currentPoint.bottom.x;
vertices[36 * i + 31] = currentPoint.bottom.y;
vertices[36 * i + 32] = currentPoint.bottom.z;
// Color
colors[48 * i + 40] = color.red;
colors[48 * i + 41] = color.green;
colors[48 * i + 42] = color.blue;
colors[48 * i + 43] = 0.0;
vertices[36 * i + 33] = currentPoint.center.x;
vertices[36 * i + 34] = currentPoint.center.y;
vertices[36 * i + 35] = currentPoint.center.z;
// Color
colors[48 * i + 44] = color.red;
colors[48 * i + 45] = color.green;
colors[48 * i + 46] = color.blue;
colors[48 * i + 47] = alpha * 0.2;
previousAlpha = alpha;
}
this.geometry.attributes.position.needsUpdate = true;
this.geometry.attributes.vertexColor.needsUpdate = true;
},
tock: function (time, delta) {
if (!this.data.enabled) { return; }
this.sampleSaberPosition();
},
sampleSaberPosition: function () {
var saberEl = this.el.querySelector('.blade');
var saberObject;
var sample;
if (!saberEl) { return; }
if (this.saberTrajectory.length === this.maxPoints) {
// Dump oldest point
sample = this.saberTrajectory.shift();
sample.top.set(0, -0.4, 0);
sample.center.set(0, 0, 0);
sample.bottom.set(0, 0.4, 0);
} else {
sample = {
top: new THREE.Vector3(0, -0.4, 0),
center: new THREE.Vector3(0, 0, 0),
bottom: new THREE.Vector3(0, 0.4, 0)
};
}
saberObject = saberEl.object3D;
saberObject.parent.updateMatrixWorld();
saberObject.localToWorld(sample.top);
saberObject.localToWorld(sample.center);
saberObject.localToWorld(sample.bottom);
this.saberTrajectory.push(sample);
this.initGeometry();
}
});