diff --git a/README.md b/README.md index 7e06061a..855043be 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,10 @@ Basic Example My Networked-Aframe Scene - + - + diff --git a/dist/networked-aframe.js b/dist/networked-aframe.js index 9fcafb4d..48ae94d9 100644 --- a/dist/networked-aframe.js +++ b/dist/networked-aframe.js @@ -94,7 +94,7 @@ /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n/* global THREE */\n\n\nvar INITIALIZING = 0;\nvar BUFFERING = 1;\nvar PLAYING = 2;\nvar MODE_LERP = 0;\nvar MODE_HERMITE = 1;\nvar vectorPool = [];\nvar quatPool = [];\nvar framePool = [];\n\nvar getPooledVector = function getPooledVector() {\n return vectorPool.shift() || new THREE.Vector3();\n};\n\nvar getPooledQuaternion = function getPooledQuaternion() {\n return quatPool.shift() || new THREE.Quaternion();\n};\n\nvar getPooledFrame = function getPooledFrame() {\n var frame = framePool.pop();\n\n if (!frame) {\n frame = {\n position: new THREE.Vector3(),\n velocity: new THREE.Vector3(),\n scale: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n time: 0\n };\n }\n\n return frame;\n};\n\nvar freeFrame = function freeFrame(f) {\n return framePool.push(f);\n};\n\nvar InterpolationBuffer = function () {\n function InterpolationBuffer() {\n var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MODE_LERP;\n var bufferTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;\n\n _classCallCheck(this, InterpolationBuffer);\n\n this.state = INITIALIZING;\n this.buffer = [];\n this.bufferTime = bufferTime * 1000;\n this.time = 0;\n this.mode = mode;\n this.originFrame = getPooledFrame();\n this.position = new THREE.Vector3();\n this.quaternion = new THREE.Quaternion();\n this.scale = new THREE.Vector3(1, 1, 1);\n }\n\n _createClass(InterpolationBuffer, [{\n key: \"hermite\",\n value: function hermite(target, t, p1, p2, v1, v2) {\n var t2 = t * t;\n var t3 = t * t * t;\n var a = 2 * t3 - 3 * t2 + 1;\n var b = -2 * t3 + 3 * t2;\n var c = t3 - 2 * t2 + t;\n var d = t3 - t2;\n target.copy(p1.multiplyScalar(a));\n target.add(p2.multiplyScalar(b));\n target.add(v1.multiplyScalar(c));\n target.add(v2.multiplyScalar(d));\n }\n }, {\n key: \"lerp\",\n value: function lerp(target, v1, v2, alpha) {\n target.lerpVectors(v1, v2, alpha);\n }\n }, {\n key: \"slerp\",\n value: function slerp(target, r1, r2, alpha) {\n THREE.Quaternion.slerp(r1, r2, target, alpha);\n }\n }, {\n key: \"updateOriginFrameToBufferTail\",\n value: function updateOriginFrameToBufferTail() {\n freeFrame(this.originFrame);\n this.originFrame = this.buffer.shift();\n }\n }, {\n key: \"appendBuffer\",\n value: function appendBuffer(position, velocity, quaternion, scale) {\n var tail = this.buffer.length > 0 ? this.buffer[this.buffer.length - 1] : null; // update the last entry in the buffer if this is the same frame\n\n if (tail && tail.time === this.time) {\n if (position) {\n tail.position.copy(position);\n }\n\n if (velocity) {\n tail.velocity.copy(velocity);\n }\n\n if (quaternion) {\n tail.quaternion.copy(quaternion);\n }\n\n if (scale) {\n tail.scale.copy(scale);\n }\n } else {\n var priorFrame = tail || this.originFrame;\n var newFrame = getPooledFrame();\n newFrame.position.copy(position || priorFrame.position);\n newFrame.velocity.copy(velocity || priorFrame.velocity);\n newFrame.quaternion.copy(quaternion || priorFrame.quaternion);\n newFrame.scale.copy(scale || priorFrame.scale);\n newFrame.time = this.time;\n this.buffer.push(newFrame);\n }\n }\n }, {\n key: \"setTarget\",\n value: function setTarget(position, velocity, quaternion, scale) {\n this.appendBuffer(position, velocity, quaternion, scale);\n }\n }, {\n key: \"setPosition\",\n value: function setPosition(position, velocity) {\n this.appendBuffer(position, velocity, null, null);\n }\n }, {\n key: \"setQuaternion\",\n value: function setQuaternion(quaternion) {\n this.appendBuffer(null, null, quaternion, null);\n }\n }, {\n key: \"setScale\",\n value: function setScale(scale) {\n this.appendBuffer(null, null, null, scale);\n }\n }, {\n key: \"update\",\n value: function update(delta) {\n if (this.state === INITIALIZING) {\n if (this.buffer.length > 0) {\n this.updateOriginFrameToBufferTail();\n this.position.copy(this.originFrame.position);\n this.quaternion.copy(this.originFrame.quaternion);\n this.scale.copy(this.originFrame.scale);\n this.state = BUFFERING;\n }\n }\n\n if (this.state === BUFFERING) {\n if (this.buffer.length > 0 && this.time > this.bufferTime) {\n this.state = PLAYING;\n }\n }\n\n if (this.state === PLAYING) {\n var mark = this.time - this.bufferTime; //Purge this.buffer of expired frames\n\n while (this.buffer.length > 0 && mark > this.buffer[0].time) {\n //if this is the last frame in the buffer, just update the time and reuse it\n if (this.buffer.length > 1) {\n this.updateOriginFrameToBufferTail();\n } else {\n this.originFrame.position.copy(this.buffer[0].position);\n this.originFrame.velocity.copy(this.buffer[0].velocity);\n this.originFrame.quaternion.copy(this.buffer[0].quaternion);\n this.originFrame.scale.copy(this.buffer[0].scale);\n this.originFrame.time = this.buffer[0].time;\n this.buffer[0].time = this.time + delta;\n }\n }\n\n if (this.buffer.length > 0 && this.buffer[0].time > 0) {\n var targetFrame = this.buffer[0];\n var delta_time = targetFrame.time - this.originFrame.time;\n var alpha = (mark - this.originFrame.time) / delta_time;\n\n if (this.mode === MODE_LERP) {\n this.lerp(this.position, this.originFrame.position, targetFrame.position, alpha);\n } else if (this.mode === MODE_HERMITE) {\n this.hermite(this.position, alpha, this.originFrame.position, targetFrame.position, this.originFrame.velocity.multiplyScalar(delta_time), targetFrame.velocity.multiplyScalar(delta_time));\n }\n\n this.slerp(this.quaternion, this.originFrame.quaternion, targetFrame.quaternion, alpha);\n this.lerp(this.scale, this.originFrame.scale, targetFrame.scale, alpha);\n }\n }\n\n if (this.state !== INITIALIZING) {\n this.time += delta;\n }\n }\n }, {\n key: \"getPosition\",\n value: function getPosition() {\n return this.position;\n }\n }, {\n key: \"getQuaternion\",\n value: function getQuaternion() {\n return this.quaternion;\n }\n }, {\n key: \"getScale\",\n value: function getScale() {\n return this.scale;\n }\n }]);\n\n return InterpolationBuffer;\n}();\n\nmodule.exports = InterpolationBuffer;\n\n//# sourceURL=webpack:///./node_modules/buffered-interpolation/dist/buffered-interpolation.js?"); +eval("\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n/* global THREE */\n\n\nvar INITIALIZING = 0;\nvar BUFFERING = 1;\nvar PLAYING = 2;\nvar MODE_LERP = 0;\nvar MODE_HERMITE = 1;\nvar vectorPool = [];\nvar quatPool = [];\nvar framePool = [];\n\nvar getPooledVector = function getPooledVector() {\n return vectorPool.shift() || new THREE.Vector3();\n};\n\nvar getPooledQuaternion = function getPooledQuaternion() {\n return quatPool.shift() || new THREE.Quaternion();\n};\n\nvar getPooledFrame = function getPooledFrame() {\n var frame = framePool.pop();\n\n if (!frame) {\n frame = {\n position: new THREE.Vector3(),\n velocity: new THREE.Vector3(),\n scale: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n time: 0\n };\n }\n\n return frame;\n};\n\nvar freeFrame = function freeFrame(f) {\n return framePool.push(f);\n};\n\nvar InterpolationBuffer = function () {\n function InterpolationBuffer() {\n var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MODE_LERP;\n var bufferTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;\n\n _classCallCheck(this, InterpolationBuffer);\n\n this.state = INITIALIZING;\n this.buffer = [];\n this.bufferTime = bufferTime * 1000;\n this.time = 0;\n this.mode = mode;\n this.originFrame = getPooledFrame();\n this.position = new THREE.Vector3();\n this.quaternion = new THREE.Quaternion();\n this.scale = new THREE.Vector3(1, 1, 1);\n }\n\n _createClass(InterpolationBuffer, [{\n key: \"hermite\",\n value: function hermite(target, t, p1, p2, v1, v2) {\n var t2 = t * t;\n var t3 = t * t * t;\n var a = 2 * t3 - 3 * t2 + 1;\n var b = -2 * t3 + 3 * t2;\n var c = t3 - 2 * t2 + t;\n var d = t3 - t2;\n target.copy(p1.multiplyScalar(a));\n target.add(p2.multiplyScalar(b));\n target.add(v1.multiplyScalar(c));\n target.add(v2.multiplyScalar(d));\n }\n }, {\n key: \"lerp\",\n value: function lerp(target, v1, v2, alpha) {\n target.lerpVectors(v1, v2, alpha);\n }\n }, {\n key: \"slerp\",\n value: function slerp(target, r1, r2, alpha) {\n target.slerpQuaternions(r1, r2, alpha);\n }\n }, {\n key: \"updateOriginFrameToBufferTail\",\n value: function updateOriginFrameToBufferTail() {\n freeFrame(this.originFrame);\n this.originFrame = this.buffer.shift();\n }\n }, {\n key: \"appendBuffer\",\n value: function appendBuffer(position, velocity, quaternion, scale) {\n var tail = this.buffer.length > 0 ? this.buffer[this.buffer.length - 1] : null; // update the last entry in the buffer if this is the same frame\n\n if (tail && tail.time === this.time) {\n if (position) {\n tail.position.copy(position);\n }\n\n if (velocity) {\n tail.velocity.copy(velocity);\n }\n\n if (quaternion) {\n tail.quaternion.copy(quaternion);\n }\n\n if (scale) {\n tail.scale.copy(scale);\n }\n } else {\n var priorFrame = tail || this.originFrame;\n var newFrame = getPooledFrame();\n newFrame.position.copy(position || priorFrame.position);\n newFrame.velocity.copy(velocity || priorFrame.velocity);\n newFrame.quaternion.copy(quaternion || priorFrame.quaternion);\n newFrame.scale.copy(scale || priorFrame.scale);\n newFrame.time = this.time;\n this.buffer.push(newFrame);\n }\n }\n }, {\n key: \"setTarget\",\n value: function setTarget(position, velocity, quaternion, scale) {\n this.appendBuffer(position, velocity, quaternion, scale);\n }\n }, {\n key: \"setPosition\",\n value: function setPosition(position, velocity) {\n this.appendBuffer(position, velocity, null, null);\n }\n }, {\n key: \"setQuaternion\",\n value: function setQuaternion(quaternion) {\n this.appendBuffer(null, null, quaternion, null);\n }\n }, {\n key: \"setScale\",\n value: function setScale(scale) {\n this.appendBuffer(null, null, null, scale);\n }\n }, {\n key: \"update\",\n value: function update(delta) {\n if (this.state === INITIALIZING) {\n if (this.buffer.length > 0) {\n this.updateOriginFrameToBufferTail();\n this.position.copy(this.originFrame.position);\n this.quaternion.copy(this.originFrame.quaternion);\n this.scale.copy(this.originFrame.scale);\n this.state = BUFFERING;\n }\n }\n\n if (this.state === BUFFERING) {\n if (this.buffer.length > 0 && this.time > this.bufferTime) {\n this.state = PLAYING;\n }\n }\n\n if (this.state === PLAYING) {\n var mark = this.time - this.bufferTime; //Purge this.buffer of expired frames\n\n while (this.buffer.length > 0 && mark > this.buffer[0].time) {\n //if this is the last frame in the buffer, just update the time and reuse it\n if (this.buffer.length > 1) {\n this.updateOriginFrameToBufferTail();\n } else {\n this.originFrame.position.copy(this.buffer[0].position);\n this.originFrame.velocity.copy(this.buffer[0].velocity);\n this.originFrame.quaternion.copy(this.buffer[0].quaternion);\n this.originFrame.scale.copy(this.buffer[0].scale);\n this.originFrame.time = this.buffer[0].time;\n this.buffer[0].time = this.time + delta;\n }\n }\n\n if (this.buffer.length > 0 && this.buffer[0].time > 0) {\n var targetFrame = this.buffer[0];\n var delta_time = targetFrame.time - this.originFrame.time;\n var alpha = (mark - this.originFrame.time) / delta_time;\n\n if (this.mode === MODE_LERP) {\n this.lerp(this.position, this.originFrame.position, targetFrame.position, alpha);\n } else if (this.mode === MODE_HERMITE) {\n this.hermite(this.position, alpha, this.originFrame.position, targetFrame.position, this.originFrame.velocity.multiplyScalar(delta_time), targetFrame.velocity.multiplyScalar(delta_time));\n }\n\n this.slerp(this.quaternion, this.originFrame.quaternion, targetFrame.quaternion, alpha);\n this.lerp(this.scale, this.originFrame.scale, targetFrame.scale, alpha);\n }\n }\n\n if (this.state !== INITIALIZING) {\n this.time += delta;\n }\n }\n }, {\n key: \"getPosition\",\n value: function getPosition() {\n return this.position;\n }\n }, {\n key: \"getQuaternion\",\n value: function getQuaternion() {\n return this.quaternion;\n }\n }, {\n key: \"getScale\",\n value: function getScale() {\n return this.scale;\n }\n }]);\n\n return InterpolationBuffer;\n}();\n\nmodule.exports = InterpolationBuffer;\n\n//# sourceURL=webpack:///./node_modules/buffered-interpolation/dist/buffered-interpolation.js?"); /***/ }), @@ -130,7 +130,7 @@ eval("// Patched version of fast-deep-equal which does not\n// allocate memory v /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nvar options = __webpack_require__(/*! ./options */ \"./src/options.js\");\n\nvar utils = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\nvar NafLogger = __webpack_require__(/*! ./NafLogger */ \"./src/NafLogger.js\");\n\nvar Schemas = __webpack_require__(/*! ./Schemas */ \"./src/Schemas.js\");\n\nvar NetworkEntities = __webpack_require__(/*! ./NetworkEntities */ \"./src/NetworkEntities.js\");\n\nvar NetworkConnection = __webpack_require__(/*! ./NetworkConnection */ \"./src/NetworkConnection.js\");\n\nvar AdapterFactory = __webpack_require__(/*! ./adapters/AdapterFactory */ \"./src/adapters/AdapterFactory.js\");\n\nvar naf = {};\nnaf.app = '';\nnaf.room = '';\nnaf.clientId = '';\nnaf.options = options;\nnaf.utils = utils;\nnaf.log = new NafLogger();\nnaf.schemas = new Schemas();\nnaf.version = \"0.8.3\";\nnaf.adapters = new AdapterFactory();\nvar entities = new NetworkEntities();\nvar connection = new NetworkConnection(entities);\nnaf.connection = connection;\nnaf.entities = entities;\nmodule.exports = window.NAF = naf;\n\n//# sourceURL=webpack:///./src/NafIndex.js?"); +eval("\n\nvar options = __webpack_require__(/*! ./options */ \"./src/options.js\");\n\nvar utils = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\nvar NafLogger = __webpack_require__(/*! ./NafLogger */ \"./src/NafLogger.js\");\n\nvar Schemas = __webpack_require__(/*! ./Schemas */ \"./src/Schemas.js\");\n\nvar NetworkEntities = __webpack_require__(/*! ./NetworkEntities */ \"./src/NetworkEntities.js\");\n\nvar NetworkConnection = __webpack_require__(/*! ./NetworkConnection */ \"./src/NetworkConnection.js\");\n\nvar AdapterFactory = __webpack_require__(/*! ./adapters/AdapterFactory */ \"./src/adapters/AdapterFactory.js\");\n\nvar naf = {};\nnaf.app = '';\nnaf.room = '';\nnaf.clientId = '';\nnaf.options = options;\nnaf.utils = utils;\nnaf.log = new NafLogger();\nnaf.schemas = new Schemas();\nnaf.version = \"0.9.0\";\nnaf.adapters = new AdapterFactory();\nvar entities = new NetworkEntities();\nvar connection = new NetworkConnection(entities);\nnaf.connection = connection;\nnaf.entities = entities;\nmodule.exports = window.NAF = naf;\n\n//# sourceURL=webpack:///./src/NafIndex.js?"); /***/ }), diff --git a/dist/networked-aframe.min.js b/dist/networked-aframe.min.js index d07ef7a1..0459ea96 100644 --- a/dist/networked-aframe.min.js +++ b/dist/networked-aframe.min.js @@ -1 +1 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){"use strict";var i=n(3),o=n(4),r=n(5),a=n(6),s=n(7),c=n(9),u=n(10),l={app:"",room:"",clientId:""};l.options=i,l.utils=o,l.log=new r,l.schemas=new a,l.version="0.8.3",l.adapters=new u;var d=new s,h=new c(d);l.connection=h,l.entities=d,e.exports=window.NAF=l},function(e,t,n){"use strict";function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n is defined."));if(!this.validateTemplate(e,t))return;this.templateCache[e.template]=document.importNode(t.content,!0)}else NAF.log.error("Schema not valid: ",e),NAF.log.error("See https://github.com/networked-aframe/networked-aframe#syncing-custom-components")}},{key:"getCachedTemplate",value:function(e){return this.templateIsCached(e)||(this.templateExistsInScene(e)?this.add(this.createDefaultSchema(e)):NAF.log.error("Template el for ".concat(e," is not in the scene, add the template to and register with NAF.schemas.add."))),this.templateCache[e].firstElementChild.cloneNode(!0)}},{key:"templateIsCached",value:function(e){return!!this.templateCache[e]}},{key:"getComponents",value:function(e){var t=["position","rotation"];return this.hasTemplate(e)&&(t=this.schemaDict[e].components),t}},{key:"hasTemplate",value:function(e){return!!this.schemaDict[e]}},{key:"templateExistsInScene",value:function(e){var t=document.querySelector(e);return t&&this.isTemplateTag(t)}},{key:"validateSchema",value:function(e){return!(!e.template||!e.components)}},{key:"validateTemplate",value:function(e,t){return this.isTemplateTag(t)?!!this.templateHasOneOrZeroChildren(t)||(NAF.log.error("Template for ".concat(e.template," has more than one child. Templates must have one direct child element, no more. Template found:"),t),!1):(NAF.log.error("Template for ".concat(e.template," is not a