123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else {
- var a = factory();
- for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
- }
- })(typeof self !== 'undefined' ? self : this, function() {
- return /******/ (function(modules) { // webpackBootstrap
- /******/ // The module cache
- /******/ var installedModules = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/
- /******/ // Check if module is in cache
- /******/ if(installedModules[moduleId]) {
- /******/ return installedModules[moduleId].exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = installedModules[moduleId] = {
- /******/ i: moduleId,
- /******/ l: false,
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/
- /******/ // Flag the module as loaded
- /******/ module.l = true;
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /******/
- /******/ // expose the modules object (__webpack_modules__)
- /******/ __webpack_require__.m = modules;
- /******/
- /******/ // expose the module cache
- /******/ __webpack_require__.c = installedModules;
- /******/
- /******/ // define getter function for harmony exports
- /******/ __webpack_require__.d = function(exports, name, getter) {
- /******/ if(!__webpack_require__.o(exports, name)) {
- /******/ Object.defineProperty(exports, name, {
- /******/ configurable: false,
- /******/ enumerable: true,
- /******/ get: getter
- /******/ });
- /******/ }
- /******/ };
- /******/
- /******/ // getDefaultExport function for compatibility with non-harmony modules
- /******/ __webpack_require__.n = function(module) {
- /******/ var getter = module && module.__esModule ?
- /******/ function getDefault() { return module['default']; } :
- /******/ function getModuleExports() { return module; };
- /******/ __webpack_require__.d(getter, 'a', getter);
- /******/ return getter;
- /******/ };
- /******/
- /******/ // Object.prototype.hasOwnProperty.call
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
- /******/
- /******/ // __webpack_public_path__
- /******/ __webpack_require__.p = "";
- /******/
- /******/ // Load entry module and return exports
- /******/ return __webpack_require__(__webpack_require__.s = 0);
- /******/ })
- /************************************************************************/
- /******/ ([
- /* 0 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- /* global AFRAME, THREE */
- if (typeof AFRAME === 'undefined') {
- throw new Error('Component attempted to register before AFRAME was available.');
- }
- // Configuration for the MutationObserver used to refresh the whitelist.
- // Listens for addition/removal of elements and attributes within the scene.
- var OBSERVER_CONFIG = {
- childList: true,
- attributes: true,
- subtree: true
- };
- /**
- * Implement AABB collision detection for entities with a mesh.
- * https://en.wikipedia.org/wiki/Minimum_bounding_box#Axis-aligned_minimum_bounding_box
- *
- * @property {string} objects - Selector of entities to test for collision.
- */
- AFRAME.registerComponent('aabb-collider', {
- schema: {
- collideNonVisible: { default: false },
- debug: { default: false },
- enabled: { default: true },
- interval: { default: 80 },
- objects: { default: '' }
- },
- init: function init() {
- this.centerDifferenceVec3 = new THREE.Vector3();
- this.clearedIntersectedEls = [];
- this.closestIntersectedEl = null;
- this.boundingBox = new THREE.Box3();
- this.boxCenter = new THREE.Vector3();
- this.boxHelper = new THREE.BoxHelper();
- this.boxMax = new THREE.Vector3();
- this.boxMin = new THREE.Vector3();
- this.hitClosestClearEventDetail = {};
- this.hitClosestEventDetail = {};
- this.intersectedEls = [];
- this.objectEls = [];
- this.newIntersectedEls = [];
- this.prevCheckTime = undefined;
- this.previousIntersectedEls = [];
- this.setDirty = this.setDirty.bind(this);
- this.observer = new MutationObserver(this.setDirty);
- this.dirty = true;
- this.hitStartEventDetail = { intersectedEls: this.newIntersectedEls };
- },
- play: function play() {
- this.observer.observe(this.el.sceneEl, OBSERVER_CONFIG);
- this.el.sceneEl.addEventListener('object3dset', this.setDirty);
- this.el.sceneEl.addEventListener('object3dremove', this.setDirty);
- },
- remove: function remove() {
- this.observer.disconnect();
- this.el.sceneEl.removeEventListener('object3dset', this.setDirty);
- this.el.sceneEl.removeEventListener('object3dremove', this.setDirty);
- },
- tick: function tick(time) {
- var boundingBox = this.boundingBox;
- var centerDifferenceVec3 = this.centerDifferenceVec3;
- var clearedIntersectedEls = this.clearedIntersectedEls;
- var el = this.el;
- var intersectedEls = this.intersectedEls;
- var newIntersectedEls = this.newIntersectedEls;
- var objectEls = this.objectEls;
- var prevCheckTime = this.prevCheckTime;
- var previousIntersectedEls = this.previousIntersectedEls;
- var closestCenterDifference = void 0;
- var newClosestEl = void 0;
- var i = void 0;
- if (!this.data.enabled) {
- return;
- }
- // Only check for intersection if interval time has passed.
- if (prevCheckTime && time - prevCheckTime < this.data.interval) {
- return;
- }
- // Update check time.
- this.prevCheckTime = time;
- if (this.dirty) {
- this.refreshObjects();
- }
- // Update the bounding box to account for rotations and position changes.
- boundingBox.setFromObject(el.object3D);
- this.boxMin.copy(boundingBox.min);
- this.boxMax.copy(boundingBox.max);
- boundingBox.getCenter(this.boxCenter);
- if (this.data.debug) {
- this.boxHelper.setFromObject(el.object3D);
- if (!this.boxHelper.parent) {
- el.sceneEl.object3D.add(this.boxHelper);
- }
- }
- copyArray(previousIntersectedEls, intersectedEls);
- // Populate intersectedEls array.
- intersectedEls.length = 0;
- for (i = 0; i < objectEls.length; i++) {
- if (objectEls[i] === this.el) {
- continue;
- }
- // Don't collide with non-visible if flag set.
- if (!this.data.collideNonVisible && !objectEls[i].getAttribute('visible')) {
- // Remove box helper if debug flag set and has box helper.
- if (this.data.debug) {
- var boxHelper = objectEls[i].object3D.boxHelper;
- if (boxHelper) {
- el.sceneEl.object3D.remove(boxHelper);
- objectEls[i].object3D.boxHelper = null;
- }
- }
- continue;
- }
- // Check for interection.
- if (this.isIntersecting(objectEls[i])) {
- intersectedEls.push(objectEls[i]);
- }
- }
- // Get newly intersected entities.
- newIntersectedEls.length = 0;
- for (i = 0; i < intersectedEls.length; i++) {
- if (previousIntersectedEls.indexOf(intersectedEls[i]) === -1) {
- newIntersectedEls.push(intersectedEls[i]);
- }
- }
- // Emit cleared events on no longer intersected entities.
- clearedIntersectedEls.length = 0;
- for (i = 0; i < previousIntersectedEls.length; i++) {
- if (intersectedEls.indexOf(previousIntersectedEls[i]) !== -1) {
- continue;
- }
- if (!previousIntersectedEls[i].hasAttribute('aabb-collider')) {
- previousIntersectedEls[i].emit('hitend');
- }
- clearedIntersectedEls.push(previousIntersectedEls[i]);
- }
- // Emit events on intersected entities. Do this after the cleared events.
- for (i = 0; i < newIntersectedEls.length; i++) {
- if (newIntersectedEls[i] === this.el) {
- continue;
- }
- if (newIntersectedEls[i].hasAttribute('aabb-collider')) {
- continue;
- }
- newIntersectedEls[i].emit('hitstart');
- }
- // Calculate closest intersected entity based on centers.
- for (i = 0; i < intersectedEls.length; i++) {
- if (intersectedEls[i] === this.el) {
- continue;
- }
- centerDifferenceVec3.copy(intersectedEls[i].object3D.boundingBoxCenter).sub(this.boxCenter);
- if (closestCenterDifference === undefined || centerDifferenceVec3.length() < closestCenterDifference) {
- closestCenterDifference = centerDifferenceVec3.length();
- newClosestEl = intersectedEls[i];
- }
- }
- // Emit events for the new closest entity and the old closest entity.
- if (!intersectedEls.length && this.closestIntersectedEl) {
- // No intersected entities, clear any closest entity.
- this.hitClosestClearEventDetail.el = this.closestIntersectedEl;
- this.closestIntersectedEl.emit('hitclosestclear');
- this.closestIntersectedEl = null;
- el.emit('hitclosestclear', this.hitClosestClearEventDetail);
- } else if (newClosestEl !== this.closestIntersectedEl) {
- // Clear the previous closest entity.
- if (this.closestIntersectedEl) {
- this.hitClosestClearEventDetail.el = this.closestIntersectedEl;
- this.closestIntersectedEl.emit('hitclosestclear', this.hitClosestClearEventDetail);
- }
- if (newClosestEl) {
- // Emit for the new closest entity.
- newClosestEl.emit('hitclosest');
- this.closestIntersectedEl = newClosestEl;
- this.hitClosestEventDetail.el = newClosestEl;
- el.emit('hitclosest', this.hitClosestEventDetail);
- }
- }
- if (clearedIntersectedEls.length) {
- el.emit('hitend');
- }
- if (newIntersectedEls.length) {
- el.emit('hitstart', this.hitStartEventDetail);
- }
- },
- /**
- * AABB collision detection.
- * 3D version of https://www.youtube.com/watch?v=ghqD3e37R7E
- */
- isIntersecting: function () {
- var boundingBox = new THREE.Box3();
- return function (el) {
- var box = void 0;
- // Dynamic, recalculate each tick.
- if (el.dataset.aabbColliderDynamic) {
- // Box.
- boundingBox.setFromObject(el.object3D);
- box = boundingBox;
- // Center.
- el.object3D.boundingBoxCenter = el.object3D.boundingBoxCenter || new THREE.Vector3();
- box.getCenter(el.object3D.boundingBoxCenter);
- }
- // Static, reuse box and centers.
- if (!el.dataset.aabbColliderDynamic) {
- if (!el.object3D.aabbBox) {
- // Box.
- el.object3D.aabbBox = new THREE.Box3().setFromObject(el.object3D);
- // Center.
- el.object3D.boundingBoxCenter = new THREE.Vector3();
- el.object3D.aabbBox.getCenter(el.object3D.boundingBoxCenter);
- }
- box = el.object3D.aabbBox;
- }
- if (this.data.debug) {
- if (!el.object3D.boxHelper) {
- el.object3D.boxHelper = new THREE.BoxHelper(el.object3D, new THREE.Color(Math.random(), Math.random(), Math.random()));
- el.sceneEl.object3D.add(el.object3D.boxHelper);
- }
- el.object3D.boxHelper.setFromObject(el.object3D);
- }
- var boxMin = box.min;
- var boxMax = box.max;
- return this.boxMin.x <= boxMax.x && this.boxMax.x >= boxMin.x && this.boxMin.y <= boxMax.y && this.boxMax.y >= boxMin.y && this.boxMin.z <= boxMax.z && this.boxMax.z >= boxMin.z;
- };
- }(),
- /**
- * Mark the object list as dirty, to be refreshed before next raycast.
- */
- setDirty: function setDirty() {
- this.dirty = true;
- },
- /**
- * Update list of objects to test for intersection.
- */
- refreshObjects: function refreshObjects() {
- var data = this.data;
- // If objects not defined, intersect with everything.
- this.objectEls = data.objects ? this.el.sceneEl.querySelectorAll(data.objects) : this.el.sceneEl.children;
- this.dirty = false;
- }
- });
- function copyArray(dest, source) {
- dest.length = 0;
- for (var i = 0; i < source.length; i++) {
- dest[i] = source[i];
- }
- }
- /***/ })
- /******/ ]);
- });
|