refactor saber-particles, attach the component to sabers. update particle position on intersection move. saber collide particles
This commit is contained in:
@@ -111,11 +111,10 @@
|
||||
|
||||
<a-mixin
|
||||
id="wall"
|
||||
data-saber-particles
|
||||
geometry
|
||||
material="shader: wallShader; tex: #noiseTexture; env: #envmapWallTexture; repeat: 2 2; transparent: true; side: double"
|
||||
wall
|
||||
saber-intersection
|
||||
></a-mixin>
|
||||
wall></a-mixin>
|
||||
|
||||
<a-mixin
|
||||
id="beatWrong"
|
||||
|
||||
@@ -8,7 +8,7 @@ AFRAME.registerComponent('haptics-saber', {
|
||||
this.isColliding = false;
|
||||
this.tick = AFRAME.utils.throttleTick(this.tick.bind(this), 100);
|
||||
|
||||
el.setAttribute('haptics__saber', {dur: 100, force: 0.1});
|
||||
el.setAttribute('haptics__saber', {dur: 100, force: 0.075});
|
||||
|
||||
el.addEventListener('mouseenter', evt => {
|
||||
if (!evt.detail || !evt.detail.intersectedEl) { return; }
|
||||
|
||||
@@ -5,7 +5,7 @@ AFRAME.registerComponent('haptics-wall', {
|
||||
init: function () {
|
||||
const el = this.el;
|
||||
this.isHittingWall = false;
|
||||
el.setAttribute('haptics__wall', {dur: 50, force: 0.1});
|
||||
el.setAttribute('haptics__wall', {dur: 50, force: 0.075});
|
||||
|
||||
this.checkIfHittingWall = this.checkIfHittingWall.bind(this);
|
||||
el.addEventListener('mouseenter', this.checkIfHittingWall);
|
||||
|
||||
@@ -326,6 +326,7 @@ AFRAME.registerComponent('particleplayer', {
|
||||
particleSystem.mesh.rotation.copy(rotation);
|
||||
particleSystem.time = 0;
|
||||
this.resetParticles(particleSystem);
|
||||
return particleSystem;
|
||||
},
|
||||
|
||||
doLoop: function (particleSystem) {
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
AFRAME.registerComponent('saber-intersection', {
|
||||
schema: {
|
||||
active: {default: true}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.hiddenIntersection = {x: 999, y: 0, z: 0};
|
||||
this.saberHit = {
|
||||
rightHand: {active: false, position: null, raycaster: null},
|
||||
leftHand: {active: false, position: null, raycaster: null}
|
||||
};
|
||||
this.particles = document.getElementById('sparkParticles');
|
||||
this.intersecting = false;
|
||||
this.saberEnterFunc = this.saberEnter.bind(this);
|
||||
this.saberLeaveFunc = this.saberLeave.bind(this);
|
||||
this.particlesPosition = {position: null, rotation: null};
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
this.el.removeAttribute('raycastable-game');
|
||||
this.el.removeEventListener('mouseenter', this.saberEnterFunc);
|
||||
this.el.removeEventListener('mouseleave', this.saberLeaveFunc);
|
||||
this.intersecting = false;
|
||||
},
|
||||
|
||||
play: function () {
|
||||
this.el.setAttribute('raycastable-game', '');
|
||||
this.el.addEventListener('mouseenter', this.saberEnterFunc);
|
||||
this.el.addEventListener('mouseleave', this.saberLeaveFunc);
|
||||
this.material = this.el.getObject3D('mesh').material;
|
||||
this.saberHit.rightHand.raycaster = document.getElementById('rightHand').components.raycaster__game;
|
||||
this.saberHit.leftHand.raycaster = document.getElementById('leftHand').components.raycaster__game;
|
||||
},
|
||||
|
||||
saberEnter: function (evt) {
|
||||
if (!this.data.active) { return; }
|
||||
const saber = this.saberHit[evt.detail.cursorEl.id];
|
||||
saber.active = true;
|
||||
var intersection = saber.raycaster.getIntersection(this.el);
|
||||
if (intersection) {
|
||||
this.particlesPosition.position = intersection.point;
|
||||
this.particles.emit('explode', this.particlesPosition, false);
|
||||
}
|
||||
this.intersecting = true;
|
||||
},
|
||||
|
||||
saberLeave: function (evt) {
|
||||
const hand = evt.detail.cursorEl.id;
|
||||
this.saberHit[hand].active = false;
|
||||
this.material.uniforms[hand == 'rightHand' ? 'hitRight' : 'hitLeft'].value = this.hiddenIntersection;
|
||||
this.intersecting = this.saberHit.rightHand.active || this.saberHit.leftHand.active;
|
||||
},
|
||||
|
||||
tick: function (time, delta) {
|
||||
if (this.data.active && this.intersecting) {
|
||||
var intersection;
|
||||
if (this.saberHit.rightHand.active) {
|
||||
intersection = this.saberHit.rightHand.raycaster.getIntersection(this.el);
|
||||
if (intersection) { this.material.uniforms.hitRight.value = intersection.point; }
|
||||
}
|
||||
if (this.saberHit.leftHand.active) {
|
||||
intersection = this.saberHit.leftHand.raycaster.getIntersection(this.el);
|
||||
if (intersection) { this.material.uniforms.hitLeft.value = intersection.point; }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
85
src/components/saber-particles.js
Normal file
85
src/components/saber-particles.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const HIT_LEFT = 'hitLeft';
|
||||
const HIT_RIGHT = 'hitRight';
|
||||
const LEFT = 'left';
|
||||
const RIGHT = 'right';
|
||||
|
||||
/**
|
||||
* Show particles when touched by saber.
|
||||
*/
|
||||
AFRAME.registerComponent('saber-particles', {
|
||||
schema: {
|
||||
enabled: {default: false},
|
||||
hand: {type: 'string'}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.hiddenIntersection = {x: 999, y: 0, z: 0};
|
||||
this.intersectedEl = null;
|
||||
|
||||
this.particles = document.getElementById('sparkParticles');
|
||||
this.particleEventDetail = {position: new THREE.Vector3(), rotation: new THREE.Euler()};
|
||||
this.particleEvent = {detail: this.particleEventDetail};
|
||||
this.particleSystem = null;
|
||||
|
||||
this.saberEnter = this.saberEnter.bind(this);
|
||||
this.saberLeave = this.saberLeave.bind(this);
|
||||
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
this.el.removeEventListener('mouseenter', this.saberEnter);
|
||||
this.el.removeEventListener('mouseleave', this.saberLeave);
|
||||
},
|
||||
|
||||
play: function () {
|
||||
this.el.addEventListener('mouseenter', this.saberEnter);
|
||||
this.el.addEventListener('mouseleave', this.saberLeave);
|
||||
this.particlesDur = this.particles.getAttribute('particleplayer').dur;
|
||||
},
|
||||
|
||||
saberEnter: function (evt) {
|
||||
if (!this.data.enabled) { return; }
|
||||
if (evt.target !== this.el) { return; }
|
||||
if (!evt.detail.intersectedEl.hasAttribute('data-saber-particles')) { return; }
|
||||
this.intersectedEl = evt.detail.intersectedEl;
|
||||
},
|
||||
|
||||
saberLeave: function (evt) {
|
||||
if (evt.detail.target !== this.el) { return; }
|
||||
|
||||
// Hide hit intersection texture.
|
||||
if (this.intersectedEl.components.wall || this.intersectedEl.id === 'floor') {
|
||||
const uniform = this.data.hand === RIGHT ? HIT_RIGHT : HIT_LEFT;
|
||||
const material = this.intersectedEl.getObject3D('mesh').material;
|
||||
material.uniforms[uniform].value = this.hiddenIntersection;
|
||||
}
|
||||
this.intersectedEl = null;
|
||||
this.particleSystem = null;
|
||||
},
|
||||
|
||||
tick: function (time, delta) {
|
||||
if (!this.data.enabled || !this.intersectedEl) { return; }
|
||||
|
||||
const raycaster = this.el.components.raycaster__game;
|
||||
const intersection = raycaster.getIntersection(this.intersectedEl);
|
||||
|
||||
if (!intersection) { return; }
|
||||
|
||||
// Update intersection material if necessary.
|
||||
if (this.intersectedEl.components.wall || this.intersectedEl.id === 'floor') {
|
||||
const uniform = this.data.hand === RIGHT ? HIT_RIGHT : HIT_LEFT;
|
||||
const material = this.intersectedEl.getObject3D('mesh').material;
|
||||
material.uniforms[uniform].value = intersection.point;
|
||||
}
|
||||
|
||||
if (this.particleSystem && this.particleSystem.active) {
|
||||
// Update particle position.
|
||||
this.particleSystem.mesh.position.copy(intersection.point);
|
||||
} else {
|
||||
// Start particle system.
|
||||
this.particleEventDetail.position.copy(intersection.point);
|
||||
this.particleSystem = this.particles.components.particleplayer.startAfterDelay(
|
||||
this.particleEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -99,7 +99,7 @@
|
||||
particleplayer="src: #mineParticlesJSON; pscale: 0.5; scale: 1.4; loop: false; on: explode; img: #sparkImg; count: 20%; animateScale: true; initialScale: 3 1 1; finalScale: 0.2 0.2 1"></a-entity>
|
||||
<a-entity
|
||||
id="sparkParticles"
|
||||
particleplayer="src: #sparksJSON; color: #fcc; pscale: 0.7; on: explode; scale: 0.3; loop: false; img: #spark2Img; dur: 700; count: 50%; animateScale: true; initialScale: 3 0.5 1; finalScale: 0.1 0.5 1"></a-entity>
|
||||
particleplayer="src: #sparksJSON; color: #fcc; pscale: 0.7; on: explode; scale: 0.1; loop: false; img: #spark2Img; dur: 700; count: 50%; animateScale: true; initialScale: 3 0.5 1; finalScale: 0.1 0.5 1"></a-entity>
|
||||
|
||||
<a-mixin
|
||||
id="cursorMesh"
|
||||
@@ -141,6 +141,7 @@
|
||||
bind__raycaster="enabled: {{ hand }}RaycasterActive"
|
||||
bind__raycaster-game="enabled: isPlaying"
|
||||
bind__saber-controls="bladeEnabled: isPlaying; isPaused: isPaused"
|
||||
bind__saber-particles="enabled: isPlaying"
|
||||
bind__trail="enabled: isPlaying"
|
||||
haptics="events: mouseenter; dur: 35; force: 0.075"
|
||||
haptics__beat="eventsFrom: #beatContainer; events: beatcollide{{ hand }}; dur: 80; force: 0.2"
|
||||
@@ -149,6 +150,7 @@
|
||||
haptics-wall
|
||||
raycaster="objects: [raycastable]; far: 5"
|
||||
raycaster__game="objects: [raycastable-game]:not(.blade{{ hand }}); far: 1; interval: 50"
|
||||
saber-particles="hand: {{ hand }}"
|
||||
saber-controls="hand: {{ hand }}"
|
||||
thumb-controls
|
||||
thumb-controls-debug="enabled: false; hand: {{ hand }}; controllerType: vive-controls"
|
||||
@@ -171,6 +173,7 @@
|
||||
scale="0.001 0.001 0.001">
|
||||
<a-entity
|
||||
class="blade blade{{ hand }}"
|
||||
{% if hand === 'right' %}data-saber-particles{% endif %}
|
||||
geometry="primitive: box; height: 0.9; depth: 0.02; width: 0.02"
|
||||
material="shader: flat; color: {{ bladeColor }}"
|
||||
raycastable-game
|
||||
|
||||
@@ -511,6 +511,8 @@ AFRAME.registerState({
|
||||
} else {
|
||||
state.loadingText = '';
|
||||
}
|
||||
|
||||
state.isPlaying = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -126,10 +126,11 @@
|
||||
|
||||
<a-entity
|
||||
id="floor"
|
||||
data-saber-particles
|
||||
geometry="primitive: plane; width: 3; height: 3"
|
||||
material="shader: floorShader; src: #floorImg; normalMap: #floorNormalsImg; envMap: #floorEnvImg"
|
||||
rotation="-90 0 0"
|
||||
bind__saber-intersection="active: isPlaying"
|
||||
raycastable-game
|
||||
stepback></a-entity>
|
||||
|
||||
<a-entity
|
||||
|
||||
Reference in New Issue
Block a user