123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
- 'use strict';
- require('./src/misc/sphere-collider');
- },{"./src/misc/sphere-collider":2}],2:[function(require,module,exports){
- 'use strict';
- /**
- * Based on aframe/examples/showcase/tracked-controls.
- *
- * Implement bounding sphere collision detection for entities with a mesh.
- * Sets the specified state on the intersected entities.
- *
- * @property {string} objects - Selector of the entities to test for collision.
- * @property {string} state - State to set on collided entities.
- *
- */
- module.exports = AFRAME.registerComponent('sphere-collider', {
- schema: {
- objects: { default: '' },
- state: { default: 'collided' },
- radius: { default: 0.05 },
- watch: { default: true }
- },
- init: function init() {
- /** @type {MutationObserver} */
- this.observer = null;
- /** @type {Array<Element>} Elements to watch for collisions. */
- this.els = [];
- /** @type {Array<Element>} Elements currently in collision state. */
- this.collisions = [];
- this.handleHit = this.handleHit.bind(this);
- this.handleHitEnd = this.handleHitEnd.bind(this);
- },
- remove: function remove() {
- this.pause();
- },
- play: function play() {
- var sceneEl = this.el.sceneEl;
- if (this.data.watch) {
- this.observer = new MutationObserver(this.update.bind(this, null));
- this.observer.observe(sceneEl, { childList: true, subtree: true });
- }
- },
- pause: function pause() {
- if (this.observer) {
- this.observer.disconnect();
- this.observer = null;
- }
- },
- /**
- * Update list of entities to test for collision.
- */
- update: function update() {
- var data = this.data;
- var objectEls = void 0;
- // Push entities into list of els to intersect.
- if (data.objects) {
- objectEls = this.el.sceneEl.querySelectorAll(data.objects);
- } else {
- // If objects not defined, intersect with everything.
- objectEls = this.el.sceneEl.children;
- }
- // Convert from NodeList to Array
- this.els = Array.prototype.slice.call(objectEls);
- },
- tick: function () {
- var position = new THREE.Vector3(),
- meshPosition = new THREE.Vector3(),
- colliderScale = new THREE.Vector3(),
- size = new THREE.Vector3(),
- box = new THREE.Box3(),
- distanceMap = new Map();
- return function () {
- var el = this.el,
- data = this.data,
- mesh = el.getObject3D('mesh'),
- collisions = [];
- var colliderRadius = void 0;
- if (!mesh) {
- return;
- }
- distanceMap.clear();
- el.object3D.getWorldPosition(position);
- el.object3D.getWorldScale(colliderScale);
- colliderRadius = data.radius * scaleFactor(colliderScale);
- // Update collision list.
- this.els.forEach(intersect);
- // Emit events and add collision states, in order of distance.
- collisions.sort(function (a, b) {
- return distanceMap.get(a) > distanceMap.get(b) ? 1 : -1;
- }).forEach(this.handleHit);
- // Remove collision state from current element.
- if (collisions.length === 0) {
- el.emit('hit', { el: null });
- }
- // Remove collision state from other elements.
- this.collisions.filter(function (el) {
- return !distanceMap.has(el);
- }).forEach(this.handleHitEnd);
- // Store new collisions
- this.collisions = collisions;
- // Bounding sphere collision detection
- function intersect(el) {
- var radius = void 0,
- mesh = void 0,
- distance = void 0,
- extent = void 0;
- if (!el.isEntity) {
- return;
- }
- mesh = el.getObject3D('mesh');
- if (!mesh) {
- return;
- }
- box.setFromObject(mesh).getSize(size);
- extent = Math.max(size.x, size.y, size.z) / 2;
- radius = Math.sqrt(2 * extent * extent);
- box.getCenter(meshPosition);
- if (!radius) {
- return;
- }
- distance = position.distanceTo(meshPosition);
- if (distance < radius + colliderRadius) {
- collisions.push(el);
- distanceMap.set(el, distance);
- }
- }
- // use max of scale factors to maintain bounding sphere collision
- function scaleFactor(scaleVec) {
- return Math.max.apply(null, scaleVec.toArray());
- }
- };
- }(),
- handleHit: function handleHit(targetEl) {
- targetEl.emit('hit');
- targetEl.addState(this.data.state);
- this.el.emit('hit', { el: targetEl });
- },
- handleHitEnd: function handleHitEnd(targetEl) {
- targetEl.emit('hitend');
- targetEl.removeState(this.data.state);
- this.el.emit('hitend', { el: targetEl });
- }
- });
- },{}]},{},[1]);
|