From b1391495b02b5879a93b79415332cc1678f8ee85 Mon Sep 17 00:00:00 2001 From: Robert Long <robert@robertlong.me> Date: Mon, 30 Oct 2017 18:28:47 -0700 Subject: [PATCH] Split personal space bubble out into two components. Perf improvements. --- public/index.html | 6 +- src/systems/personal-space-bubble.js | 94 +++++++++++++++++----------- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/public/index.html b/public/index.html index 718096f24..e2b306f7f 100644 --- a/public/index.html +++ b/public/index.html @@ -35,12 +35,12 @@ matcolor-audio-feedback="objectName: DodecAvatar_Head_0" scale-audio-feedback avatar-customization - personal-space-bubble + personal-space-invader ></a-entity> </script> <script id="hand-template" type="text/html"> - <a-box class="hand" personal-space-bubble scale="0.2 0.1 0.3"></a-box> + <a-box class="hand" personal-space-invader scale="0.2 0.1 0.3"></a-box> </script> <script id="nametag-template" type="text/html"> @@ -55,7 +55,7 @@ <a-entity id="player-rig" networked wasd-controls snap-rotation="pivotSrc: #head"> <a-sphere scale="0.1 0.1 0.1"></a-sphere> - <a-entity id="head" camera="userHeight: 1.6" look-controls networked="template:#head-template;showLocalTemplate:false;"></a-entity> + <a-entity id="head" camera="userHeight: 1.6" personal-space-bubble look-controls networked="template:#head-template;showLocalTemplate:false;"></a-entity> <a-entity id="nametag" networked="template:#nametag-template;showLocalTemplate:false;"></a-entity> diff --git a/src/systems/personal-space-bubble.js b/src/systems/personal-space-bubble.js index 5b8121ad9..9087ec5a4 100644 --- a/src/systems/personal-space-bubble.js +++ b/src/systems/personal-space-bubble.js @@ -1,73 +1,93 @@ -var posA = new AFRAME.THREE.Vector3(); -var posB = new AFRAME.THREE.Vector3(); - -function distance(entityA, entityB) { - entityA.object3D.getWorldPosition(posA); - entityB.object3D.getWorldPosition(posB); - return posA.distanceTo(posB); -} +var invaderPos = new AFRAME.THREE.Vector3(); +var bubblePos = new AFRAME.THREE.Vector3(); AFRAME.registerSystem("personal-space-bubble", { init() { - this.myEntities = []; - this.entities = []; + this.invaders = []; + this.bubbles = []; }, - registerEntity(el) { - var networkedEl = NAF.utils.getNetworkedEntity(el); - var owner = NAF.utils.getNetworkOwner(networkedEl); + registerBubble(el) { + this.bubbles.push(el); + }, - if (owner !== NAF.clientId) { - this.entities.push(el); - } else { - this.myEntities.push(el); + unregisterBubble(el) { + var index = this.bubbles.indexOf(el); + + if (index !== -1) { + this.bubbles.splice(index, 1); } }, - unregisterEntity(el) { + registerInvader(el) { var networkedEl = NAF.utils.getNetworkedEntity(el); var owner = NAF.utils.getNetworkOwner(networkedEl); if (owner !== NAF.clientId) { - var index = this.entities.indexOf(el); - this.entities.splice(index, 1); - } else { - var index = this.myEntities.indexOf(el); - this.myEntities.splice(index, 1); + this.invaders.push(el); + } + }, + + unregisterInvader(el) { + var index = this.invaders.indexOf(el); + + if (index !== -1) { + this.invaders.splice(index, 1); } }, tick() { - for (var j = 0; j < this.entities.length; j++) { - var otherEntity = this.entities[j]; + // Update matrix positions once for each space bubble and space invader + for (var i = 0; i < this.bubbles.length; i++) { + this.bubbles[i].object3D.updateMatrixWorld(true); + } + + for (var i = 0; i < this.invaders.length; i++) { + this.invaders[i].object3D.updateMatrixWorld(true); + } - var visible = true; + // Loop through all of the space bubbles (usually one) + for (var i = 0; i < this.bubbles.length; i++) { + var bubble = this.bubbles[i]; - for (var i = 0; i < this.myEntities.length; i++) { - var myEntity = this.myEntities[i]; + bubblePos.setFromMatrixPosition(bubble.object3D.matrixWorld); - var d = distance(myEntity, otherEntity); + var radius = bubble.components["personal-space-bubble"].data.radius; + var radiusSquared = radius * radius; - if (d < myEntity.components["personal-space-bubble"].data.radius) { - visible = false; - break; - } - } + // Hide the invader if inside the bubble + for (var j = 0; j < this.invaders.length; j++) { + var invader = this.invaders[j]; + + invaderPos.setFromMatrixPosition(invader.object3D.matrixWorld); - otherEntity.object3D.visible = visible; + var distanceSquared = bubblePos.distanceTo(invaderPos); + + invader.object3D.visible = distanceSquared > radiusSquared; + } } } }); +AFRAME.registerComponent("personal-space-invader", { + init() { + this.el.sceneEl.systems["personal-space-bubble"].registerInvader(this.el); + }, + + remove() { + this.el.sceneEl.systems["personal-space-bubble"].unregisterInvader(this.el); + } +}); + AFRAME.registerComponent("personal-space-bubble", { schema: { radius: { type: "number", default: 0.8 } }, init() { - this.system.registerEntity(this.el); + this.system.registerBubble(this.el); }, remove() { - this.system.unregisterEntity(this.el); + this.system.unregisterBubble(this.el); } }); -- GitLab