diff --git a/README.md b/README.md
index c439b8c..c92f6b4 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ This is a fully functional example of what A-Frame code looks like.
-
+
- *
+ *
*
*
*
@@ -96,7 +96,7 @@
*
*/
AFRAME.registerComponent('altspace', {
- version: '1.3.0',
+ version: '1.3.1',
schema: {
usePixelScale: { type: 'boolean', default: 'false'},
verticalAlign: { type: 'string', default: 'middle'},
@@ -398,6 +398,14 @@
* @namespace native
*/
(function () {
+ if (!window.altspace || !altspace.inClient) {
+ var noop = function () {};
+ window.altspace = {
+ addNativeComponent: noop,
+ updateNativeComponent: noop,
+ removeNativeComponent: noop
+ };
+ }
var placeholderGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);
var placeholderMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
@@ -408,16 +416,22 @@
PlaceholderMesh.prototype = Object.create( THREE.Mesh.prototype );
PlaceholderMesh.prototype.constructor = THREE.PlaceholderMesh;
- function nativeComponentInit() {
- var mesh = this.el.getOrCreateObject3D('mesh', PlaceholderMesh);
-
+ function meshInit(mesh) {
//If you attach native components to an entity, it will not use a default collider
mesh.userData.altspace = mesh.userData.altspace || {};
mesh.userData.altspace.collider = mesh.userData.altspace.collider || {};
mesh.userData.altspace.collider.enabled = false;
altspace.addNativeComponent(mesh, this.name);
- this.update(this.data);//to pass defaults
+ }
+
+ function nativeComponentInit() {
+ var mesh = this.el.getOrCreateObject3D('mesh', PlaceholderMesh);
+
+ meshInit.call(this, mesh);
+
+ //to pass defaults
+ this.update(this.data);
}
function nativeComponentRemove() {
var mesh = this.el.getObject3D('mesh');
@@ -432,13 +446,13 @@
}
/**
- * Attach a given native object to this entity.
- * @mixin n-object
+ * Attach a given native object to this entity.
+ * @mixin n-object
* @memberof native
- * @prop {string} res - The identifier for the resource you want. This component
+ * @prop {string} res - The identifier for the resource you want. This component
* can accept all resources except for `interactables`.
- * @example
- */
+ * @example
+ */
AFRAME.registerComponent('n-object', {
schema: {
res: {type: 'string'}
@@ -449,15 +463,15 @@
});
/**
- * Create an object that spawns additional copies of itself when grabbed by a user (the copies are not spawners themselves).
+ * Create an object that spawns additional copies of itself when grabbed by a user (the copies are not spawners themselves).
* These copies will be physically interactive and automatically synchronized
* between users.
- * @mixin n-spawner
+ * @mixin n-spawner
* @memberof native
- * @prop {string} res - The identifier for the resource you want. This component
+ * @prop {string} res - The identifier for the resource you want. This component
* can only accept resources of type `interactables`.
- * @example
- */
+ * @example
+ */
AFRAME.registerComponent('n-spawner', {
schema: {
res: {type: 'string'}
@@ -468,21 +482,21 @@
});
/**
- * Creates dynamic 2D text on the entity. The text will wrap automatically based on the width and height provided.
- * This text will be clearer than texture-based text and more performant than geometry-based test.
- * @mixin n-text
+ * Creates dynamic 2D text on the entity. The text will wrap automatically based on the width and height provided.
+ * This text will be clearer than texture-based text and more performant than geometry-based test.
+ * @mixin n-text
* @memberof native
- * @prop {string} text - The text to be drawn.
- * @prop {number} fontSize=10 - The height of the letters. 10pt ~= 1m
- * @prop {number} width=10 - The width of the text area in meters. If the
- * text is wider than this value, the overflow will be wrapped to the next line.
- * @prop {number} height=1 - The height of the text area in meters. If the
- * text is taller than this value, the overflow will be cut off.
- * @prop {string} horizontalAlign=middle - The horizontal anchor point for
- * the text. Can be `left`, `middle`, or `right`.
- * @prop {string} verticalAlign=middle - The vertical anchor point for the
- * text. Can be `top`, `middle`, or `bottom`.
- */
+ * @prop {string} text - The text to be drawn.
+ * @prop {number} fontSize=10 - The height of the letters. 10pt ~= 1m
+ * @prop {number} width=10 - The width of the text area in meters. If the
+ * text is wider than this value, the overflow will be wrapped to the next line.
+ * @prop {number} height=1 - The height of the text area in meters. If the
+ * text is taller than this value, the overflow will be cut off.
+ * @prop {string} horizontalAlign=middle - The horizontal anchor point for
+ * the text. Can be `left`, `middle`, or `right`.
+ * @prop {string} verticalAlign=middle - The vertical anchor point for the
+ * text. Can be `top`, `middle`, or `bottom`.
+ */
AFRAME.registerComponent('n-text', {
init: nativeComponentInit,
update: nativeComponentUpdate,
@@ -516,7 +530,7 @@
* @name n-collider
* @mixin n-collider
* @memberof native
- * @prop {vec3} center=0,0,0 - The offset of the collider in local space.
+ * @prop {vec3} center=0,0,0 - The offset of the collider in local space.
* @prop {string} type=hologram - The type of collider, one of: `object` | `environment` | `hologram`.
* Object colliders collide with other objects, the environment, and the cursor.
* Environment colliders collide with everything objects do, but you can also
@@ -524,13 +538,13 @@
* the cursor.
*/
- /**
- * Create a spherical collider on this entity.
- * @mixin n-sphere-collider
+ /**
+ * Create a spherical collider on this entity.
+ * @mixin n-sphere-collider
* @memberof native
* @extends native.n-collider
- * @prop {number} radius=1 - The size of the collider in meters.
- */
+ * @prop {number} radius=1 - The size of the collider in meters.
+ */
AFRAME.registerComponent('n-sphere-collider', {
init:nativeComponentInit,
remove: nativeComponentRemove,
@@ -545,12 +559,12 @@
/**
- * Create a box-shaped collider on this entity.
- * @mixin n-box-collider
+ * Create a box-shaped collider on this entity.
+ * @mixin n-box-collider
* @memberof native
* @extends native.n-collider
- * @prop {vec3} size=1,1,1 - The dimensions of the collider.
- */
+ * @prop {vec3} size=1,1,1 - The dimensions of the collider.
+ */
AFRAME.registerComponent('n-box-collider', {
init:nativeComponentInit,
remove: nativeComponentRemove,
@@ -564,16 +578,16 @@
});
/**
- * Create a capsule-shaped collider on this entity. Capsules
- * are a union of a cylinder and two spheres on top and bottom.
- * @mixin n-capsule-collider
+ * Create a capsule-shaped collider on this entity. Capsules
+ * are a union of a cylinder and two spheres on top and bottom.
+ * @mixin n-capsule-collider
* @memberof native
* @extends native.n-collider
- * @prop {number} radius=1 - The radius of the capsule in meters.
- * @prop {number} height=1 - The height of the shaft of the capsule in meters.
- * @prop {string} direction=y - The axis with which the capsule is aligned.
- * One of `x`, `y`, or `z`.
- */
+ * @prop {number} radius=1 - The radius of the capsule in meters.
+ * @prop {number} height=1 - The height of the shaft of the capsule in meters.
+ * @prop {string} direction=y - The axis with which the capsule is aligned.
+ * One of `x`, `y`, or `z`.
+ */
AFRAME.registerComponent('n-capsule-collider', {
init:nativeComponentInit,
remove: nativeComponentRemove,
@@ -589,17 +603,60 @@
});
/**
- * Enable collision for the entire attached mesh. This is expensive to evaluate, so should only be used on
- * low-poly meshes.
- * @mixin n-mesh-collider
+ * Enable collision for the entire attached mesh. This is expensive to evaluate, so should only be used on
+ * low-poly meshes.
+ * @mixin n-mesh-collider
* @memberof native
* @extends native.n-collider
- * @example
- */
+ * @example
+ * @prop {bool} convex=true - Whether the collider should be convex or concave. Set this to false if you have holes
+ * in your mesh. Convex colliders are limited to 255 triangles. Note: concave colliders can be significantly more
+ * expensive comparet to conves colliders.
+ */
AFRAME.registerComponent('n-mesh-collider', {
- init:nativeComponentInit,
- remove: nativeComponentRemove,
- update: nativeComponentUpdate,
+ _forEachMesh: function (func) {
+ var obj = this.el.object3DMap.mesh;
+ if (!obj) { return; }
+ if (obj instanceof THREE.Mesh) {
+ func(obj);
+ }
+ obj.traverse(function (childObj) {
+ if (childObj instanceof THREE.Mesh) {
+ func(childObj);
+ }
+ }.bind(this));
+ },
+ _initObj: function () {
+ this._forEachMesh(function (mesh) {
+ meshInit.call(this, mesh);
+
+ //to pass defaults
+ altspace.updateNativeComponent(mesh, this.name, this.data);
+ }.bind(this));
+ },
+ init: function () {
+ // Allow a-frame to create a PlaceholderMesh if there isn't already one, so that the native collider is
+ // registered.
+ this.el.getOrCreateObject3D('mesh', PlaceholderMesh);
+
+ // Initialize the existing mesh
+ this._initObj();
+
+ this.el.addEventListener('model-loaded', function () {
+ // Re-initialize the collider if a new model is loaded
+ this._initObj();
+ }.bind(this));
+ },
+ remove: function () {
+ this._forEachMesh(function (mesh) {
+ altspace.removeNativeComponent(mesh, this.name);
+ }.bind(this));
+ },
+ update: function (oldData) {
+ this._forEachMesh(function (mesh) {
+ altspace.updateNativeComponent(mesh, this.name, this.data);
+ }.bind(this));
+ },
schema: {
isTrigger: { default: false, type: 'boolean' },
convex: { default: true, type: 'boolean' },
@@ -608,26 +665,26 @@
});
/**
- * Make the object's +Z always face the viewer. Currently will only directly apply to main mesh or native component on the attached entity, not any children or submeshes.
- * @mixin n-billboard
+ * Make the object's +Z always face the viewer. Currently will only directly apply to main mesh or native component on the attached entity, not any children or submeshes.
+ * @mixin n-billboard
* @memberof native
- * @example
- */
+ * @example
+ */
AFRAME.registerComponent('n-billboard', {
init:nativeComponentInit,
remove: nativeComponentRemove,
});
/**
- * A container keeps a running tally of how many objects are within
- * its bounds, and adds and removes the states `container-full` and
+ * A container keeps a running tally of how many objects are within
+ * its bounds, and adds and removes the states `container-full` and
* `container-empty` based on the current count of objects. Can fire three
* special events: `container-full`, `container-empty`, and `container-count-changed`.
- * @mixin n-container
+ * @mixin n-container
* @memberof native
- * @prop {number} capacity=4 - The value at which the container will fire the
- * `container-full` event.
- */
+ * @prop {number} capacity=4 - The value at which the container will fire the
+ * `container-full` event.
+ */
AFRAME.registerComponent('n-container', {
init: function(){
nativeComponentInit.call(this);
@@ -655,12 +712,12 @@
}
});
- /**
- * Play the sound given by the `src` or `res` property from the location
+ /**
+ * Play the sound given by the `src` or `res` property from the location
* of the entity.
- * @mixin n-sound
+ * @mixin n-sound
* @memberof native
- * @prop {string} res - The resource identifier for a built-in sound clip.
+ * @prop {string} res - The resource identifier for a built-in sound clip.
* @prop {string} src - A URL to an external sound clip. The sound can be in WAV, OGG or MP3 format. However. only
* WAV is supported on all platforms. MP3 is supported on Gear VR and OGG is supported on desktop.
* @prop {string} on - The name of the event that will play this sound clip.
@@ -683,7 +740,7 @@
* If rolloff is 'linear' or 'cosine', the sound will be silent at this distance.
* @prop {string} rolloff='logarithmic' - Set this to 'linear' or 'cosine' if you want to cut sounds off at a
* maxDistance.
- */
+ */
/**
* Fired when a sound has loaded and is ready to be played
* @event native.n-sound#n-sound-loaded
diff --git a/dist/aframe-altspace-component.min.js b/dist/aframe-altspace-component.min.js
old mode 100644
new mode 100755
index ceb5950..10c7459
--- a/dist/aframe-altspace-component.min.js
+++ b/dist/aframe-altspace-component.min.js
@@ -1 +1 @@
-!function(e){function t(i){if(n[i])return n[i].exports;var a=n[i]={exports:{},id:i,loaded:!1};return e[i].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");n(3),n(1),n(2),n(4),n(5),n(10),n(8),n(9),n(6),n(7),n(11)},function(e,t){!function(){function e(e,t){e.userData.altspace={collider:{enabled:t}},e.traverse(function(e){e instanceof THREE.Mesh&&(e.userData.altspace={collider:{enabled:t}})})}AFRAME.registerComponent("altspace-cursor-collider",{schema:{enabled:{"default":!0}},init:function(){e(this.el.object3D,this.data.enabled),this.el.addEventListener("model-loaded",function(){e(this.el.object3D,this.data.enabled)}.bind(this))},update:function(){e(this.el.object3D,this.data.enabled)}})}()},function(e,t){AFRAME.registerComponent("altspace-tracked-controls",{init:function(){this.gamepadIndex=null,this.trackedControlsSystem=document.querySelector("a-scene").systems["tracked-controls"],this.systemGamepads=0,altspace.getGamepads()},tick:function(){if(this.trackedControlsSystem&&this.systemGamepads!==this.trackedControlsSystem.controllers.length&&window.altspace&&altspace.getGamepads&&altspace.getGamepads().length){var e=this.el.components;e["paint-controls"]&&(this.gamepadIndex="left"===e["paint-controls"].data.hand?2:1),null===this.gamepadIndex&&e["hand-controls"]&&(this.gamepadIndex="left"===e["hand-controls"].data?2:1),null===this.gamepadIndex&&e["vive-controls"]&&(this.gamepadIndex="left"===e["vive-controls"].data.hand?2:1),null===this.gamepadIndex&&e["tracked-controls"]&&(this.gamepadIndex=e["tracked-controls"].data.controller),this.el.setAttribute("tracked-controls","id",altspace.getGamepads()[this.gamepadIndex].id),this.el.setAttribute("tracked-controls","controller",0),this.systemGamepads=this.trackedControlsSystem.controllers.length}}})},function(e,t){AFRAME.registerComponent("altspace",{version:"1.3.0",schema:{usePixelScale:{type:"boolean","default":"false"},verticalAlign:{type:"string","default":"middle"},enclosuresOnly:{type:"boolean","default":"true"},fullspace:{type:"boolean","default":"false"}},init:function(){return this.el.object3D instanceof THREE.Scene?void(window.altspace&&window.altspace.inClient?(this.el.setAttribute("vr-mode-ui",{enabled:!1}),this.initRenderer(),this.initCursorEvents(),this.initCollisionEvents()):console.warn("aframe-altspace-component only works inside of AltspaceVR")):void console.warn("aframe-altspace-component can only be attached to a-scene")},tick:function(e,t){this.el.object3D.updateAllBehaviors&&this.el.object3D.updateAllBehaviors()},remove:function(){},pause:function(){},play:function(){},initRenderer:function(){var e=this.el.object3D;altspace.getEnclosure().then(function(n){switch(this.data.fullspace&&(n.requestFullspace(),n.addEventListener("fullspacechange",function(){e.scale.setScalar(n.pixelsPerMeter)})),this.data.usePixelScale&&!this.data.fullspace||e.scale.setScalar(n.pixelsPerMeter),this.data.verticalAlign){case"bottom":e.position.y-=n.innerHeight/2;break;case"top":e.position.y+=n.innerHeight/2;break;case"middle":break;default:console.warn("Unexpected value for verticalAlign: ",this.data.verticalAlign)}this.data.enclosuresOnly&&1===n.innerDepth&&(this.el.renderer.render(new THREE.Scene),this.el.renderer=this.el.effect=t)}.bind(this));var t=this.el.renderer,n=this.el.renderer=this.el.effect=altspace.getThreeJSRenderer({aframeComponentVersion:this.version}),i=function(){};n.setSize=i,n.setPixelRatio=i,n.setClearColor=i,n.clear=i,n.enableScissorTest=i,n.setScissor=i,n.setViewport=i,n.getPixelRatio=i,n.getMaxAnisotropy=i,n.setFaceCulling=i,n.context={canvas:{}},n.shadowMap={}},initCursorEvents:function(){var e=this.el.object3D,t=document.querySelector("a-cursor")||document.querySelector("a-entity[cursor]");t&&(t.setAttribute("material","transparent",!0),t.setAttribute("material","opacity",0));var n=function(e,n){var i=n.target.el;t&&t.emit(e,{target:i,ray:n.ray,point:n.point}),i&&i.emit(e,{target:i,ray:n.ray,point:n.point})},i=null;e.addEventListener("cursordown",function(e){i=e.target,n("mousedown",e)}),e.addEventListener("cursorup",function(e){n("mouseup",e),e.target.uuid===i.uuid&&n("click",e),i=null}),e.addEventListener("cursorenter",function(e){e.target.el&&(e.target.el.addState("hovered"),t&&t.addState("hovering"),n("mouseenter",e))}),e.addEventListener("cursorleave",function(e){e.target.el&&(e.target.el.removeState("hovered"),t&&t.removeState("hovering"),n("mouseleave",e))})},initCollisionEvents:function(){var e=this.el.object3D,t=function(e,t){var n=t.target.el;n&&(t.target=n,t.other&&t.other.el&&(t.other=t.other.el),n.emit(e,t))};e.addEventListener("collisionenter",function(e){t("collisionenter",e)}),e.addEventListener("collisionexit",function(e){t("collisionexit",e)}),e.addEventListener("triggerenter",function(e){t("triggerenter",e)}),e.addEventListener("triggerexit",function(e){t("triggerexit",e)})}})},function(e,t){!function(){function e(){var e=this.el.getOrCreateObject3D("mesh",o);e.userData.altspace=e.userData.altspace||{},e.userData.altspace.collider=e.userData.altspace.collider||{},e.userData.altspace.collider.enabled=!1,altspace.addNativeComponent(e,this.name),this.update(this.data)}function t(){var e=this.el.getObject3D("mesh");altspace.removeNativeComponent(e,this.name)}function n(e){altspace.updateNativeComponent(this.el.object3DMap.mesh,this.name,this.data)}function i(e,t){altspace.callNativeComponent(this.el.object3DMap.mesh,this.name,e,t)}var a=new THREE.BoxGeometry(.001,.001,.001),s=new THREE.MeshBasicMaterial({color:0});s.visible=!1;var o=function(){THREE.Mesh.call(this,a,s)};o.prototype=Object.create(THREE.Mesh.prototype),o.prototype.constructor=THREE.PlaceholderMesh,AFRAME.registerComponent("n-object",{schema:{res:{type:"string"}},init:e,update:n,remove:t}),AFRAME.registerComponent("n-spawner",{schema:{res:{type:"string"}},init:e,update:n,remove:t}),AFRAME.registerComponent("n-text",{init:e,update:n,remove:t,schema:{text:{"default":"",type:"string"},fontSize:{"default":"10",type:"int"},width:{"default":"10",type:"number"},height:{"default":"1",type:"number"},horizontalAlign:{"default":"middle"},verticalAlign:{"default":"middle"}}}),AFRAME.registerComponent("n-sphere-collider",{init:e,remove:t,update:n,schema:{isTrigger:{"default":!1,type:"boolean"},center:{type:"vec3"},radius:{"default":"0",type:"number"},type:{"default":"object"}}}),AFRAME.registerComponent("n-box-collider",{init:e,remove:t,update:n,schema:{isTrigger:{"default":!1,type:"boolean"},center:{type:"vec3"},size:{type:"vec3"},type:{"default":"object"}}}),AFRAME.registerComponent("n-capsule-collider",{init:e,remove:t,update:n,schema:{isTrigger:{"default":!1,type:"boolean"},center:{type:"vec3"},radius:{"default":"0",type:"number"},height:{"default":"0",type:"number"},direction:{"default":"y"},type:{"default":"object"}}}),AFRAME.registerComponent("n-mesh-collider",{init:e,remove:t,update:n,schema:{isTrigger:{"default":!1,type:"boolean"},convex:{"default":!0,type:"boolean"},type:{"default":"object"}}}),AFRAME.registerComponent("n-billboard",{init:e,remove:t}),AFRAME.registerComponent("n-container",{init:function(){e.call(this);var t=this.el,n=this;t.addEventListener("stateadded",function(e){"container-full"===e.detail.state&&t.emit("container-full"),"container-empty"===e.detail.state&&t.emit("container-empty")}),t.addEventListener("container-count-changed",function(e){n.count=e.detail.count})},remove:t,update:n,schema:{capacity:{"default":4,type:"number"}}}),AFRAME.registerComponent("n-sound",{init:function(){var t=this.data.src;if(t&&!t.startsWith("http"))if(t.startsWith("/"))this.data.src=location.origin+t;else{var n=location.pathname;n.endsWith("/")||(n=location.pathname.split("/").slice(0,-1).join("/")+"/"),this.data.src=location.origin+n+t}e.call(this)},pauseSound:function(){i.call(this,"pause"),this.el.emit("sound-paused")},playSound:function(){i.call(this,"play"),this.el.emit("sound-played")},seek:function(e){i.call(this,"seek",{time:e})},remove:function(){t.call(this),this.playHandler&&this.el.removeEventListener(oldData.on,this.playHandler)},update:function(e){n.call(this,e),this.playHandler&&this.el.removeEventListener(e.on,this.playHandler),this.data.on&&(this.playHandler=this.playSound.bind(this),this.el.addEventListener(this.data.on,this.playHandler))},schema:{on:{type:"string"},res:{type:"string"},src:{type:"string"},loop:{type:"boolean"},volume:{type:"number","default":1},autoplay:{type:"boolean"},oneshot:{type:"boolean"},spatialBlend:{type:"float","default":1},pitch:{type:"float","default":1},minDistance:{type:"float","default":1},maxDistance:{type:"float","default":12},rolloff:{type:"string","default":"logarithmic"}}})}()},function(e,t){},function(e,t){AFRAME.registerComponent("sync-color",{dependencies:["sync"],schema:{},init:function(){function e(){var e=n.dataRef.child("material/color"),i=!1,a=!0;t.el.addEventListener("componentchanged",function(t){var a=t.detail.name,s=t.detail.oldData,o=t.detail.newData;"material"===a&&(i||s.color!==o.color&&n.isMine&&setTimeout(function(){e.set(o.color)},0))}),e.on("value",function(e){if(!n.isMine||a){var s=e.val();i=!0,t.el.setAttribute("material","color",s),i=!1,a=!1}})}var t=this,n=t.el.components.sync;n.isConnected?e():t.el.addEventListener("connected",e)}})},function(e,t){AFRAME.registerComponent("sync-n-sound",{dependencies:["sync"],schema:{},init:function(){function e(){function e(e){if(n.isMine){var e={type:e.type,sender:a.clientId,el:t.el.id,time:Date.now()};t.soundEventRef.set(e)}}t.soundStateRef=n.dataRef.child("sound/state"),t.soundEventRef=n.dataRef.child("sound/event"),t.el.addEventListener("sound-played",e),t.el.addEventListener("sound-paused",e),t.soundEventRef.on("value",function(e){if(!n.isMine){var i=e.val();if(i&&i.el===t.el.id){var a=t.el.components["n-sound"];"sound-played"===i.type?a.playSound():a.pauseSound()}}}),t.el.addEventListener("componentchanged",function(e){if(n.isMine){var i=e.detail.name;"n-sound"===i&&t.soundStateRef.set(e.detail.newData)}}),t.soundStateRef.on("value",function(e){if(!n.isMine){var i=e.val();i&&t.el.setAttribute("n-sound",i)}})}var t=this,n=t.el.components.sync,i=document.querySelector("a-scene"),a=i.systems["sync-system"];n.isConnected?e():t.el.addEventListener("connected",e)},remove:function(){this.soundStateRef.off("value"),this.soundEventRef.off("value")}})},function(e,t){AFRAME.registerSystem("sync-system",{schema:{author:{type:"string","default":null},app:{type:"string","default":null},instance:{type:"string","default":null},refUrl:{type:"string","default":null}},init:function(){var e=this;return this.data&&this.data.app?(e.isConnected=!1,console.log(this.data),void altspace.utilities.sync.connect({authorId:this.data.author,appId:this.data.app,instanceId:this.data.instance,baseRefUrl:this.data.refUrl}).then(function(t){this.connection=t,this.sceneRef=this.connection.instance.child("scene"),this.clientsRef=this.connection.instance.child("clients"),this.clientId=this.sceneEl.object3D.uuid;var n;this.clientsRef.on("value",function(e){var t=e.val(),i=Object.keys(t)[0];n=t[i]}),this.clientsRef.on("child_added",function(t){var n=t.val();setTimeout(function(){e.sceneEl.emit("clientjoined",{id:n},!1)},0)}),this.clientsRef.on("child_removed",function(t){var n=t.val();setTimeout(function(){e.sceneEl.emit("clientleft",{id:n},!1)},0)}),this.clientsRef.push(this.clientId).onDisconnect().remove(),this.connection.instance.child("initialized").once("value",function(t){var n=!t.val();t.ref().set(!0),e.sceneEl.emit("connected",{shouldInitialize:n},!1),e.isConnected=!0}.bind(this)),Object.defineProperty(this,"isMasterClient",{get:function(){return n===this.clientId}.bind(this)})}.bind(this))):void console.warn("The sync-system must be present on the scene and configured with required data.")}})},function(e,t){AFRAME.registerComponent("sync-transform",{dependencies:["sync"],schema:{},init:function(){function e(){function e(e,i){if(!n.isMine){var a=e.val();a&&t.el.setAttribute(i,a)}}function i(e){if(n.isMine){var t=e.detail.name,i=e.detail.newData;if("position"===t)c(i);else if("rotation"===t)d(i);else{if("scale"!==t)return;u(i)}}}function a(e,t,n){var i,a,s,o,r=0;n||(n={});var l=function(){r=n.leading===!1?0:Date.now(),i=null,o=e.apply(a,s),i||(a=s=null)},c=function(){var c=Date.now();r||n.leading!==!1||(r=c);var d=t-(c-r);return a=this,s=arguments,d<=0||d>t?(i&&(clearTimeout(i),i=null),r=c,o=e.apply(a,s),i||(a=s=null)):i||n.trailing===!1||(i=setTimeout(l,d)),o};return c.cancel=function(){clearTimeout(i),r=0,i=a=s=null},c}var s=n.dataRef.child("position"),o=n.dataRef.child("rotation"),r=n.dataRef.child("scale");t.updateRate=100;var l=[];t.el.addEventListener("ownershiplost",function(){for(var e=t.el.children,n=0;nt?(i&&(clearTimeout(i),i=null),r=c,o=e.apply(a,s),i||(a=s=null)):i||n.trailing===!1||(i=setTimeout(l,d)),o};return c.cancel=function(){clearTimeout(i),r=0,i=a=s=null},c}var s=n.dataRef.child("position"),o=n.dataRef.child("rotation"),r=n.dataRef.child("scale");t.updateRate=100;var l=[];t.el.addEventListener("ownershiplost",function(){for(var e=t.el.children,n=0;nQuick Start
This is a fully functional example of what A-Frame code l
<!DOCTYPE html>
<html><head>
<script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
-<script src="https://cdn.rawgit.com/AltspaceVR/aframe-altspace-component/v1.3.0/dist/aframe-altspace-component.min.js"></script>
+<script src="https://cdn.rawgit.com/AltspaceVR/aframe-altspace-component/v1.3.1/dist/aframe-altspace-component.min.js"></script>
<script>
// an example custom component, that will change the color when clicked
diff --git a/doc/native.n-mesh-collider.html b/doc/native.n-mesh-collider.html
index a4dbd0f..2e6ed73 100644
--- a/doc/native.n-mesh-collider.html
+++ b/doc/native.n-mesh-collider.html
@@ -60,6 +60,68 @@
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
convex
+
+
+
+
+
+bool
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
Whether the collider should be convex or concave. Set this to false if you have holes
+in your mesh. Convex colliders are limited to 255 triangles. Note: concave colliders can be significantly more
+expensive comparet to conves colliders.