337 lines
11 KiB
JavaScript
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();
|
|
}
|
|
});
|