use raycaster over aabb-collider for saber collisions

This commit is contained in:
Kevin Ngo
2018-11-04 19:28:10 +08:00
parent 0139133dc3
commit 36b7032418
7 changed files with 45 additions and 33 deletions

View File

@@ -60,8 +60,6 @@
<a-mixin id="gameoverAnimation" animation__gameover="dur: 1000; easing: easeOutQuad"></a-mixin> <a-mixin id="gameoverAnimation" animation__gameover="dur: 1000; easing: easeOutQuad"></a-mixin>
<a-mixin id="mine" mixin="beat" beat="type: mine"></a-mixin> <a-mixin id="mine" mixin="beat" beat="type: mine"></a-mixin>
<a-mixin id="wall" geometry wall material="shader: wall-shader; tex: #noiseTexture; env: #envmapWallTexture; repeat: 2 2; transparent: true; side: double">
<a-mixin <a-mixin
id="beatScore" id="beatScore"
mixin="font" mixin="font"
@@ -70,7 +68,13 @@
animation__opacityout="property: components.text.material.uniforms.opacity.value; from: 1; to: 0; dur: 500; delay: 700; startEvents: startanim" animation__opacityout="property: components.text.material.uniforms.opacity.value; from: 1; to: 0; dur: 500; delay: 700; startEvents: startanim"
animation__motionz="property: object3D.position.z; from: -2; to: -6; dur: 500; easing: easeOutQuart; startEvents: startanim" animation__motionz="property: object3D.position.z; from: -2; to: -6; dur: 500; easing: easeOutQuart; startEvents: startanim"
animation__motiony="property: object3D.position.y; to: 0.1; dur: 500; easing: easeOutQuart; startEvents: startanim" animation__motiony="property: object3D.position.y; to: 0.1; dur: 500; easing: easeOutQuart; startEvents: startanim"
></a-mixin> ></a-mixin>
<a-mixin
id="wall"
geometry
material="shader: wall-shader; tex: #noiseTexture; env: #envmapWallTexture; repeat: 2 2; transparent: true; side: double"
wall>
<a-mixin <a-mixin
id="beatWrong" id="beatWrong"

View File

@@ -5,6 +5,10 @@
AFRAME.registerComponent('cursor-laser', { AFRAME.registerComponent('cursor-laser', {
dependencies: ['geometry'], dependencies: ['geometry'],
schema: {
enabled: {default: true}
},
init: function () { init: function () {
const el = this.el; const el = this.el;
const box = new THREE.Box3(); const box = new THREE.Box3();
@@ -21,9 +25,15 @@ AFRAME.registerComponent('cursor-laser', {
this.currentLength = size.y; this.currentLength = size.y;
}, },
update: function () {
this.el.object3D.visible = this.data.enabled;
},
tick: function () { tick: function () {
const el = this.el; const el = this.el;
if (!this.data.enabled) { return; }
const cursor = el.parentNode.components.cursor; const cursor = el.parentNode.components.cursor;
if (!cursor) { return; } if (!cursor) { return; }

View File

@@ -2,15 +2,16 @@
* Haptics when sabers collide. * Haptics when sabers collide.
*/ */
AFRAME.registerComponent('haptics-saber', { AFRAME.registerComponent('haptics-saber', {
dependencies: ['aabb-collider'],
init: function () { init: function () {
const el = this.el; const el = this.el;
el.setAttribute('haptics__saber', {dur: 100, force: 0.025}); el.setAttribute('haptics__saber', {dur: 100, force: 0.025});
el.addEventListener('hitclosest', evt => { el.addEventListener('mouseenter', evt => {
if (!evt.detail || !evt.detail.el.classList.contains('saber') || if (!evt.detail || !evt.detail.intersectedEl) { return; }
evt.detail.el === el) { return; }
const intersectedEl = evt.detail.intersectedEl;
if (!intersectedEl.classList.contains('blade') || intersectedEl === el) { return; }
this.el.components.haptics__saber.pulse(); this.el.components.haptics__saber.pulse();
}); });
} }

View File

@@ -2,16 +2,14 @@
* Listen to aabb-collider event for wall haptics. * Listen to aabb-collider event for wall haptics.
*/ */
AFRAME.registerComponent('haptics-wall', { AFRAME.registerComponent('haptics-wall', {
dependencies: ['aabb-collider'],
init: function () { init: function () {
const el = this.el; const el = this.el;
this.isHittingWall = false; this.isHittingWall = false;
el.setAttribute('haptics__wall', {dur: 50, force: 0.025}); el.setAttribute('haptics__wall', {dur: 50, force: 0.025});
this.checkIfHittingWall = this.checkIfHittingWall.bind(this); this.checkIfHittingWall = this.checkIfHittingWall.bind(this);
el.addEventListener('hitstart', this.checkIfHittingWall); el.addEventListener('mouseenter', this.checkIfHittingWall);
el.addEventListener('hitend', this.checkIfHittingWall); el.addEventListener('mouseleave', this.checkIfHittingWall);
this.tick = AFRAME.utils.throttleTick(this.tick.bind(this), 50); this.tick = AFRAME.utils.throttleTick(this.tick.bind(this), 50);
}, },
@@ -20,7 +18,7 @@ AFRAME.registerComponent('haptics-wall', {
* On aabb-collider event, check if we are still hitting a wall. * On aabb-collider event, check if we are still hitting a wall.
*/ */
checkIfHittingWall: function () { checkIfHittingWall: function () {
const intersectedEls = this.el.components['aabb-collider'].intersectedEls; const intersectedEls = this.el.components.raycaster__game.intersectedEls;
this.isHittingWall = false; this.isHittingWall = false;
for (let i = 0; i < intersectedEls.length; i++) { for (let i = 0; i < intersectedEls.length; i++) {
if (intersectedEls[i].components.wall) { if (intersectedEls[i].components.wall) {

View File

@@ -1 +0,0 @@
AFRAME.registerComponent('raycastable', {});

View File

@@ -13,13 +13,13 @@ AFRAME.registerComponent('wall', {
pause: function () { pause: function () {
this.el.object3D.visible = false; this.el.object3D.visible = false;
this.el.removeAttribute('data-collidable-head'); this.el.removeAttribute('data-collidable-head');
this.el.removeAttribute('data-collidable-saber'); this.el.removeAttribute('raycastable-game');
}, },
play: function () { play: function () {
this.el.object3D.visible = true; this.el.object3D.visible = true;
this.el.setAttribute('data-collidable-head', ''); this.el.setAttribute('data-collidable-head', '');
this.el.setAttribute('data-collidable-saber', ''); this.el.setAttribute('raycastable-game', '');
}, },
tock: function (time, delta) { tock: function (time, delta) {
@@ -35,6 +35,6 @@ AFRAME.registerComponent('wall', {
this.el.object3D.position.z = 9999; this.el.object3D.position.z = 9999;
this.el.pause(); this.el.pause();
this.el.removeAttribute('data-collidable-head'); this.el.removeAttribute('data-collidable-head');
this.el.removeAttribute('data-collidable-saber'); this.el.removeAttribute('raycastable-game');
} }
}); });

View File

@@ -86,10 +86,6 @@
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> 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>
<!-- Player. --> <!-- Player. -->
<a-mixin
id="raycaster"
raycaster="objects: [raycastable]; far: 3; showLine: false"
line="opacity: 0.75"></a-mixin>
<a-mixin <a-mixin
id="cursorMesh" id="cursorMesh"
material="shader: flat; transparent: true; src: #cursorMeshImg; depthTest: false" material="shader: flat; transparent: true; src: #cursorMeshImg; depthTest: false"
@@ -114,19 +110,23 @@
bind__menu-controls="page: search.page; selectedChallengeId: menuSelectedChallenge.id" bind__menu-controls="page: search.page; selectedChallengeId: menuSelectedChallenge.id"
bind__pauser="enabled: isPlaying" bind__pauser="enabled: isPlaying"
bind__raycaster="enabled: {{ hand }}RaycasterActive" bind__raycaster="enabled: {{ hand }}RaycasterActive"
bind__raycaster-game="enabled: isPlaying"
bind__saber-controls="bladeEnabled: isPlaying; isPaused: isPaused" bind__saber-controls="bladeEnabled: isPlaying; isPaused: isPaused"
bind__trail="enabled: isPlaying" bind__trail="enabled: isPlaying"
haptics="events: mouseenter; dur: 35; force: 0.075" haptics="events: mouseenter; dur: 35; force: 0.075"
haptics__beat="eventsFrom: #beatContainer; events: beatcollide{{ hand }}; dur: 80; force: 0.2" haptics__beat="eventsFrom: #beatContainer; events: beatcollide{{ hand }}; dur: 80; force: 0.2"
haptics__draw="events: drawblade; dur: 750; force: 0.025" haptics__draw="events: drawblade; dur: 750; force: 0.025"
haptics-saber
haptics-wall
raycaster="objects: [raycastable]; far: 5"
raycaster__game="objects: [raycastable-game]:not(.blade{{ hand }}); far: 1; interval: 50"
saber-controls="hand: {{ hand }}" saber-controls="hand: {{ hand }}"
thumb-controls thumb-controls
thumb-controls-debug="enabled: false; hand: {{ hand }}; controllerType: vive-controls" thumb-controls-debug="enabled: false; hand: {{ hand }}; controllerType: vive-controls"
trail="color: {{ bladeColor }}; hand: {{ hand }}"> trail="color: {{ bladeColor }}; hand: {{ hand }}">
<a-entity <a-entity
id="{{ hand }}Laser" id="{{ hand }}Laser"
bind__visible="menuActive && activeHand === '{{ hand }}'" bind__cursor-laser="enabled: menuActive && activeHand === '{{ hand }}'"
cursor-laser
geometry="primitive: cylinder; height: 1; radius: 0.005" geometry="primitive: cylinder; height: 1; radius: 0.005"
material="color: {{ beamColor }}; shader: flat" material="color: {{ beamColor }}; shader: flat"
rotation="-90 0 0"></a-entity> rotation="-90 0 0"></a-entity>
@@ -138,14 +138,10 @@
animation="property: scale; from: 0 0 0; to: 1 1 1; dur: 750; easing: linear; startEvents: drawblade" animation="property: scale; from: 0 0 0; to: 1 1 1; dur: 750; easing: linear; startEvents: drawblade"
scale="0.001 0.001 0.001"> scale="0.001 0.001 0.001">
<a-entity <a-entity
class="blade" class="blade blade{{ hand }}"
bind__aabb-collider="enabled: isPlaying"
bind-toggle__data-collidable-saber="isPlaying"
aabb-collider="objects: [data-collidable-saber]; interval: 50; collideNonVisible: false"
geometry="primitive: box; height: 0.9; depth: 0.02; width: 0.02" geometry="primitive: box; height: 0.9; depth: 0.02; width: 0.02"
haptics-saber
haptics-wall
material="shader: flat; color: {{ bladeColor }}" material="shader: flat; color: {{ bladeColor }}"
raycastable-game
position="0 -0.55 0"></a-entity> position="0 -0.55 0"></a-entity>
</a-entity> </a-entity>
<a-entity <a-entity
@@ -177,8 +173,8 @@
<a-entity <a-entity
id="{{ hand }}CursorMesh" id="{{ hand }}CursorMesh"
mixin="cursorMesh" mixin="cursorMesh"
bind__cursor-mesh="active: {{ hand }}RaycasterActive" bind__cursor-mesh="active: {{ hand }}RaycasterActive && !isPLaying"
cursor-mesh="active: {{ hand }}RaycasterActive; cursorEl: #{{ hand }}Hand" cursor-mesh="cursorEl: #{{ hand }}Hand"
material="color: {{ beamColor }}" material="color: {{ beamColor }}"
scale="1.3 1.3 1.3"></a-entity> scale="1.3 1.3 1.3"></a-entity>
{% endmacro %} {% endmacro %}
@@ -195,8 +191,12 @@
material="shader: flat; src: #stepbackImg; transparent: true; opacity: 0"></a-entity> material="shader: flat; src: #stepbackImg; transparent: true; opacity: 0"></a-entity>
{% if not IS_PRODUCTION %} {% if not IS_PRODUCTION %}
<a-entity id="mouseCursor" mixin="raycaster" cursor="rayOrigin: mouse" <a-entity
bind__raycaster="enabled: !inVR"></a-entity> id="mouseCursor"
bind__raycaster="enabled: !inVR"
mixin="raycaster"
cursor="rayOrigin: mouse"
raycaster="objects: [raycastable]"></a-entity>
<a-entity id="mouseCursorMesh" mixin="cursorMesh" cursor-mesh="cursorEl: #mouseCursor" <a-entity id="mouseCursorMesh" mixin="cursorMesh" cursor-mesh="cursorEl: #mouseCursor"
bind__cursor-mesh="active: menuActive"></a-entity> bind__cursor-mesh="active: menuActive"></a-entity>
{% endif %} {% endif %}