diff --git a/README.md b/README.md
index ca77be35..c719a802 100755
--- a/README.md
+++ b/README.md
@@ -447,6 +447,22 @@ This is a core component in our framework that explores learning around tools an
```
+- [circles-networked-basic](https://github.com/PlumCantaloupe/circlesxr/blob/main/src/components/circles-networked-basic.js): **_[ Experimental ]_** This component allows the any object to be shared with other connected clients. It also attempts to handle cases of when clients disconnecting, and remove the duplication of networked object basic networked-aframe objects have. Unlike _circles-pickup-networked_ these objects do not need to be interactive and cannot be picked up. This networked component also enables A-Frame's _[text](https://github.com/aframevr/aframe/blob/master/docs/components/text.md)_ to be synched.
+
+ _NOTE!!: ALl circles-networked objects require an element id_
+
+ | Property | Type | Description | Default Value |
+ |--------------------|-----------------|-----------------------------------------------------------|----------------------|
+ | networkedEnabled | boolean | turn off and on networking of this object to others | true |
+ | networkedTemplate | string | Name of networked template | CIRCLES.NETWORKED_TEMPLATES.INTERACTIVE_OBJECT |
+
+ *Example 'circles-networked-basic'*
+
+ ```html
+
+
+ ```
+
- [circles-pickup-object](https://github.com/PlumCantaloupe/circlesxr/blob/main/src/components/circles-pickup-object.js): This component allows you to pickup and drop objects on click.
| Property | Type | Description | Default Value |
@@ -466,7 +482,9 @@ This is a core component in our framework that explores learning around tools an
```
-- [circles-pickup-networked](https://github.com/PlumCantaloupe/circlesxr/blob/main/src/components/circles-pickup-object.js): **_[ Experimental ]_** This component allows the _circles-pickup-object_ to be shared with other connected clients. It also attempts to handle cases of when clients disconnecting.
+- [circles-pickup-networked](https://github.com/PlumCantaloupe/circlesxr/blob/main/src/components/circles-pickup-object.js): **_[ Experimental ]_** This component allows the _circles-pickup-object_ to be shared with other connected clients. It also attempts to handle cases of when clients disconnecting, and remove the duplication of networked object basic networked-aframe objects have.
+
+ _NOTE!!: ALl circles-networked objects require an element id_
| Property | Type | Description | Default Value |
|--------------------|-----------------|-----------------------------------------------------------|----------------------|
@@ -477,7 +495,7 @@ This is a core component in our framework that explores learning around tools an
```html
-
+
```
- [circles-pdf-loader](https://github.com/PlumCantaloupe/circlesxr/blob/main/src/components/circles-pdf-loader.js): **_[ Experimental ]_** A component to load in PDFs with basic next page annd previous page controls.
@@ -616,21 +634,35 @@ CIRCLES.getAllNAFElements();
CONTEXT_AF.socket = null;
CONTEXT_AF.campfireEventName = "campfire_event";
-//this is the event to listen to before trying to get a reference to the communication socket
-CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, function (data) {
- CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket(); //get socket
-
- //let the user click on the campfire to turn it on/off, and then after let all other clients know it has been toggled
- CONTEXT_AF.campfire.addEventListener('click', function () {
- CONTEXT_AF.fireOn = !CONTEXT_AF.fireOn;
-
- //change (this) client current world
- CONTEXT_AF.turnFire(CONTEXT_AF.fireOn);
-
- //send event to change other client's worlds. Use CIRCLES object to get relevant infomation i.e., room and world. Room is used to know where server will send message.
- CONTEXT_AF.socket.emit(CONTEXT_AF.campfireEventName, {campfireOn:CONTEXT_AF.fireOnue, room:CIRCLES.getCirclesGroupName(), world:CIRCLES.getCirclesWorldName()});
- }
-});
+ //create a function we can call to get all our networked stuff connected
+ CONTEXT_AF.createNetworkingSystem = function () {
+ CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket(); //get socket
+
+ //let the user click on the campfire to turn it on/off, and then after let all other clients know it has been toggled
+ CONTEXT_AF.campfire.addEventListener('click', function () {
+ CONTEXT_AF.fireOn = !CONTEXT_AF.fireOn;
+
+ //change (this) client current world
+ CONTEXT_AF.turnFire(CONTEXT_AF.fireOn);
+
+ //send event to change other client's worlds. Use CIRCLES object to get relevant infomation i.e., room and world. Room is used to know where server will send message.
+ CONTEXT_AF.socket.emit(CONTEXT_AF.campfireEventName, {campfireOn:CONTEXT_AF.fireOnue, room:CIRCLES.getCirclesGroupName(), world:CIRCLES.getCirclesWorldName()});
+ }
+ };
+
+ //check if circle networking is ready. If not, listen for network event to call out network setup function
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ CONTEXT_AF.createNetworkingSystem();
+ }
+ else {
+ const wsReadyFunc = function() {
+ CONTEXT_AF.createNetworkingSystem();
+
+ //always good practise to remove eventlisteners we are not using
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ };
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ }
//listen for when others turn on campfire
CONTEXT_AF.socket.on(CONTEXT_AF.campfireEventName, function(data) {
diff --git a/src/components/circles-button.js b/src/components/circles-button.js
index b51dd40f..5862ec78 100644
--- a/src/components/circles-button.js
+++ b/src/components/circles-button.js
@@ -2,11 +2,12 @@
AFRAME.registerComponent('circles-button', {
schema: {
- type: {type:'string', default:'box', oneOf:['box', 'cylinder']},
- button_color: {type:'color', default:'rgb(255, 100, 100)'},
+ type: {type:'string', default:'box', oneOf:['box', 'cylinder']},
+ button_color: {type:'color', default:'rgb(255, 100, 100)'},
button_color_hover: {type:'color', default:'rgb(255, 0, 0)'},
- pedastal_color: {type:'color', default:'rgb(255, 255, 255)'},
- diameter: {type:'number', default:0.5}
+ pedastal_color: {type:'color', default:'rgb(255, 255, 255)'},
+ diameter: {type:'number', default:0.5},
+ pedastal_visible: {type:'boolean', default:true}
},
init: function () {
const CONTEXT_AF = this;
@@ -71,5 +72,9 @@ AFRAME.registerComponent('circles-button', {
CONTEXT_AF.button.setAttribute('scale', {x:data.diameter, y:1, z:data.diameter});
CONTEXT_AF.button_pedastal.setAttribute('scale', {x:data.diameter, y:1, z:data.diameter});
}
+
+ if ( (oldData.pedastal_visible !== data.pedastal_visible) && (data.pedastal_visible !== '') ) {
+ CONTEXT_AF.button_pedastal.setAttribute('visible', data.pedastal_visible);
+ }
}
});
\ No newline at end of file
diff --git a/src/components/circles-interactive-object.js b/src/components/circles-interactive-object.js
index df98da5d..ddef3e18 100644
--- a/src/components/circles-interactive-object.js
+++ b/src/components/circles-interactive-object.js
@@ -4,7 +4,7 @@
AFRAME.registerComponent('circles-interactive-object', {
schema: {
- type: {type:'string', default:'none', oneOf:['outline','scale','highlight','none']},
+ type: {type:'string', default:'highlight', oneOf:['outline','scale','highlight','none']},
highlight_color: {type:'color', default:'rgb(255,255,255)'}, //only for outline and highlight effect
neutral_scale: {type:'number', default:1.00}, //only for outline effect
hover_scale: {type:'number', default:1.08},
diff --git a/src/components/circles-label.js b/src/components/circles-label.js
index 6580cdf7..779f60da 100644
--- a/src/components/circles-label.js
+++ b/src/components/circles-label.js
@@ -4,7 +4,7 @@ AFRAME.registerComponent('circles-label', {
schema: {
text: {type:'string', default:'label_text'},
offset: {type:'vec3', default:{x:0.0, y:0.0, z:0.0}},
- arrow_position: {type:'string', default:'down', oneOf: ['up', 'down', 'left', 'right']},
+ arrow_position: {type:'string', default:'down', oneOf: ['up', 'down', 'left', 'right' ]},
arrow_visible: {type:'boolean', default:true},
lookAtCamera: {type:'boolean', default:true},
constrainYAxis: {type:'boolean', default:true},
diff --git a/src/components/circles-networked-basic.js b/src/components/circles-networked-basic.js
new file mode 100644
index 00000000..03faf2c1
--- /dev/null
+++ b/src/components/circles-networked-basic.js
@@ -0,0 +1,318 @@
+//for when we want an object in the scene that is not duplicated on other clients and can be interacted with by other players
+
+'use strict';
+
+AFRAME.registerComponent('circles-networked-basic', {
+ schema: {
+ className: {type:'string', default:''}, //We will randomly generate one if need be. The class we will use to synch with the networked version
+ networkedEnabled: {type:'boolean', default:true},
+ networkedTemplate:{type:'string', default:CIRCLES.NETWORKED_TEMPLATES.BASIC_OBJECT}
+ },
+ init: function() {
+ const CONTEXT_AF = this;
+ const data = CONTEXT_AF.data;
+ CONTEXT_AF.socket = null;
+ CONTEXT_AF.isShowing = true;
+ CONTEXT_AF.listenersAttached = false;
+
+ //we will track this so that if a hosting client disappears we can set new data here to synch new hosting client
+ CONTEXT_AF.lastKnowObjectData = null;
+
+ //CONTEXT_AF.el.setAttribute('circles-interactive-visible', false); //hide on init, then show later
+
+ let regex = /(naf)/i;
+ CONTEXT_AF.isClone = regex.test(CONTEXT_AF.el.id); //if false, this entity is the sole networked object of all duplicates
+
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ CONTEXT_AF.createEventFunctions(); //will only do this once at beginning of program
+ }
+ else {
+ const wsReadyFunc = function() {
+ CONTEXT_AF.createEventFunctions(); //will only do this once at beginning of program
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ };
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ }
+
+ //this is so we can keep track of which world this object is from so we can share objects, but turning that off for now to reduce duplicate object complexity.
+ if (CONTEXT_AF.isClone === false) {
+ CONTEXT_AF.el.setAttribute('circles-object-world', {});
+ }
+
+ CONTEXT_AF.origId = CONTEXT_AF.el.components['circles-object-world'].data.id
+ },
+ update : function(oldData) {
+ const CONTEXT_AF = this;
+ const data = this.data;
+
+ if (Object.keys(data).length === 0) { return; } // No need to update. as nothing here yet
+
+ if ( oldData.className !== data.className ) {
+ //autogenerate
+ if (data.className === '') {
+ const randomClassName = CIRCLES.UTILS.generateRandomString(5);
+ CONTEXT_AF.el.classList.add(randomClassName);
+ CONTEXT_AF.el.setAttribute('circles-networked-basic', {className:randomClassName});
+ }
+ }
+
+ if ( (oldData.networkedEnabled !== data.networkedEnabled) && (data.networkedEnabled !== '') ) {
+ CONTEXT_AF.enableNetworking(data.networkedEnabled, !CONTEXT_AF.isClone);
+ }
+ },
+ remove : function() {
+ if(CIRCLES.isCirclesWebsocketReady() === true) {
+ //let everyone know (maybe helpful in future)
+ CIRCLES.getCirclesWebsocket().emit(CIRCLES.EVENTS.OBJECT_NETWORKED_DETACHED, this.getNetworkDataObject());
+ }
+
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ this.removeEventListeners();
+ }
+ },
+ createEventFunctions: function() {
+ const CONTEXT_AF = this;
+ CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
+
+ //NAf events
+ CONTEXT_AF.ownerGainedFunc = null;
+ CONTEXT_AF.ownerLostFunc = null;
+
+ //circles networking events
+ CONTEXT_AF.networkAttachedFunc = null;
+ CONTEXT_AF.networkDetachedFunc = null;
+
+ CONTEXT_AF.ownerGainedFunc = function(e) {
+ //console.log('ownerGainedFunc', CONTEXT_AF.el.id);
+ };
+
+ CONTEXT_AF.ownerLostFunc = function(e) {
+ //console.log('ownerLostFunc', CONTEXT_AF.el.id);
+ };
+
+ CONTEXT_AF.captureNewHostingObjectData = function(elem) {
+ //console.log('captureNewHostingObjectData', elem);
+ if (elem) {
+ CONTEXT_AF.lastKnowObjectData = { position: {x:elem.object3D.position.x, y:elem.object3D.position.y, z:elem.object3D.position.z},
+ rotation: {x:elem.object3D.rotation.x, y:elem.object3D.rotation.y, z:elem.object3D.rotation.z},
+ scale: {x:elem.object3D.scale.x, y:elem.object3D.scale.y, z:elem.object3D.scale.z},
+ circlesObjectWorld: elem.getAttribute('circles-object-world')
+ };
+ }
+ }
+
+ CONTEXT_AF.networkAttachedFunc = function(data) {
+ //console.log('networkAttachedFunc', CONTEXT_AF.el.id);
+
+ const isSameWorld = (data.world === CIRCLES.getCirclesWorldName());
+ const isSameElem = (data.origId === CONTEXT_AF.origId);
+ if (isSameWorld && isSameElem) {
+ if (CONTEXT_AF.isClone === true) {
+ //make sure label click works on networked elements (if artefact)
+ const labelEl = document.querySelector('#' + CONTEXT_AF.origId + '_label');
+ if (labelEl) {
+ labelEl.querySelector('.label_bg').addEventListener('click', CONTEXT_AF.clickLabelFunc);
+ }
+ }
+ }
+ };
+
+ CONTEXT_AF.networkDetachedFunc = function(data) {
+ //console.log('networkDetachedFunc', CONTEXT_AF.el.id);
+
+ const isSameWorld = (data.world === CIRCLES.getCirclesWorldName());
+ const isSameElem = (data.origId === CONTEXT_AF.origId);
+ if (isSameWorld && isSameElem) {
+ //CONTEXT_AF.initSyncObjects();
+ }
+ };
+
+ //need this be always listening so that "hidden" objects can come back
+ if (CONTEXT_AF.isClone === false) {
+ document.body.addEventListener('clientConnected', function(e) {
+ //console.log('NAF clientConnected', e.detail.clientId);
+ });
+
+ document.body.addEventListener('clientDisconnected', function(e) {
+ //console.log('NAF clientDisconnected', e.detail.clientId);
+ });
+
+ document.body.addEventListener('entityCreated', function(e) {
+ //console.log('NAF entityCreated', e.detail.el);
+
+ if (!e.detail.el.components['circles-object-world']) {
+ return;
+ }
+
+ if (CONTEXT_AF.isClone === false && e.detail.el.components['circles-object-world'].data.id === CONTEXT_AF.origId) {
+ CONTEXT_AF.initSyncObjects();
+ }
+ });
+
+ document.body.addEventListener('entityRemoved', function(e) {
+ //console.log('NAF entityRemoved', e.detail.networkId);
+ if (CONTEXT_AF.isClone === false) {
+ CONTEXT_AF.initSyncObjects();
+ }
+ });
+ }
+ },
+ addEventListeners: function() {
+ //console.log('addEventListeners');
+
+ const CONTEXT_AF = this;
+ CONTEXT_AF.listenersAttached = true;
+ CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
+
+ CONTEXT_AF.el.addEventListener('ownership-gained', CONTEXT_AF.ownerGainedFunc);
+ CONTEXT_AF.el.addEventListener('ownership-lost', CONTEXT_AF.ownerLostFunc);
+
+ CONTEXT_AF.socket.on(CIRCLES.EVENTS.OBJECT_NETWORKED_ATTACHED, CONTEXT_AF.networkAttachedFunc);
+ CONTEXT_AF.socket.on(CIRCLES.EVENTS.OBJECT_NETWORKED_DETACHED, CONTEXT_AF.networkDetachedFunc);
+ },
+ removeEventListeners: function() {
+ //console.log('removeEventListeners');
+
+ const CONTEXT_AF = this;
+ CONTEXT_AF.listenersAttached = false;
+ CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
+
+ CONTEXT_AF.el.removeEventListener('ownership-gained', CONTEXT_AF.ownerGainedFunc);
+ CONTEXT_AF.el.removeEventListener('ownership-lost', CONTEXT_AF.ownerLostFunc);
+
+ CONTEXT_AF.socket.off(CIRCLES.EVENTS.OBJECT_NETWORKED_ATTACHED, CONTEXT_AF.networkAttachedFunc);
+ CONTEXT_AF.socket.off(CIRCLES.EVENTS.OBJECT_NETWORKED_DETACHED, CONTEXT_AF.networkDetachedFunc);
+ },
+ getNetworkDataObject: function() {
+ const networkId_ = (this.el.hasAttribute('networked')) ? this.el.components['networked'].data.networkId : '';
+ return {id:this.el.id, origId:this.origId, networkId:networkId_, room:CIRCLES.getCirclesGroupName(), world:CIRCLES.getCirclesWorldName()};
+ },
+ initSyncObjects: function() {
+ //console.log('initSyncObjects');
+
+ const CONTEXT_AF = this;
+
+ //console.log('initSyncObjects', this.el.id);
+ //if there already exists "the same element" then hide this and turn off networking (if this is not a clone)
+ //get list of the "same" objects, and remove the one that is duplicate ...
+ let numSimilarNetObjs = 0;
+ let oldestTime = 0;
+ let currAgeMS = 0;
+ let oldestElem = null;
+ let isSameWorld = false;
+ let isSameElem = false;
+ const allNetworkObjects = document.querySelectorAll('[circles-networked-basic]');
+
+ //console.log(allNetworkObjects);
+
+ allNetworkObjects.forEach(function(netObj) {
+ isSameWorld = (netObj.components['circles-object-world'].data.world === CIRCLES.getCirclesWorldName());
+ isSameElem = (netObj.components['circles-object-world'].data.id === CONTEXT_AF.origId);
+
+ if (isSameWorld && isSameElem) {
+ currAgeMS = netObj.components['circles-object-world'].data.timeCreated;
+ if (currAgeMS > oldestTime) {
+ oldestTime = currAgeMS;
+ oldestElem = netObj;
+ }
+
+ if (netObj.components['circles-object-world'].data.id === CONTEXT_AF.origId && netObj.components['circles-networked-basic'].isShowing === true) {
+ //console.log(CONTEXT_AF.el.id, CONTEXT_AF.origId, netObj.id, netObj.components['circles-object-world'].data.id, netObj.components['circles-networked-basic'].isShowing);
+ numSimilarNetObjs++;
+ }
+ }
+ });
+
+ if (oldestElem) {
+ //if more than one, hide this one, if it is the oldest ...
+ if (numSimilarNetObjs > 1) {
+ if (CONTEXT_AF.isShowing === true && oldestElem.id === CONTEXT_AF.el.id) {
+ CONTEXT_AF.showThisElement(false, true);
+ }
+ }
+ //if 0 elements that means that a remote owner disappeared and we must bring the other one to fruition
+ else if (numSimilarNetObjs === 0 && oldestElem.id === CONTEXT_AF.el.id) {
+ //am owner
+ if (CONTEXT_AF.isShowing === false) {
+ //you are now the host/owner of this networked object
+ CONTEXT_AF.showThisElement(true, true);
+
+ if (CONTEXT_AF.lastKnowObjectData) {
+ //determine last state and set this new one to a similar one
+ if (CONTEXT_AF.lastKnowObjectData.circlesObjectWorld.pickedup === true) {
+ //this isn't the pickup component
+ }
+ else {
+ //set world coordinates
+ CONTEXT_AF.el.object3D.position.set(CONTEXT_AF.lastKnowObjectData.position.x, CONTEXT_AF.lastKnowObjectData.position.y, CONTEXT_AF.lastKnowObjectData.position.z);
+ CONTEXT_AF.el.object3D.rotation.set(CONTEXT_AF.lastKnowObjectData.rotation.x, CONTEXT_AF.lastKnowObjectData.rotation.y, CONTEXT_AF.lastKnowObjectData.rotation.z);
+ CONTEXT_AF.el.object3D.scale.set(CONTEXT_AF.lastKnowObjectData.scale.x, CONTEXT_AF.lastKnowObjectData.scale.y, CONTEXT_AF.lastKnowObjectData.scale.z);
+ }
+ }
+ }
+ }
+ }
+ },
+ enableNetworking: function(enable, alertNetwork) {
+ //console.log('enableNetworking', this.el.id, enable, alertNetwork);
+
+ const CONTEXT_AF = this;
+
+ //don't want to touch the networked component if a clone
+ if (CONTEXT_AF.isClone === false) {
+ if (enable === true) {
+ if (CONTEXT_AF.listenersAttached === false) {
+ CONTEXT_AF.el.setAttribute('networked', {template:'#' + CONTEXT_AF.data.networkedTemplate, attachTemplateToLocal:true, synchWorldTransforms:true}); //broken in NAF - persistent:true});
+ }
+ }
+ else {
+ CONTEXT_AF.el.removeAttribute('networked');
+ }
+ }
+
+ //need everyone to send this message
+ const networkReadyFunc = function() {
+ //console.log('networkReadyFunc');
+ if (enable === true) {
+ if (alertNetwork === true) {
+ CIRCLES.getCirclesWebsocket().emit(CIRCLES.EVENTS.OBJECT_NETWORKED_ATTACHED, CONTEXT_AF.getNetworkDataObject() );
+ }
+ if (CONTEXT_AF.listenersAttached === false) {
+ CONTEXT_AF.addEventListeners();
+ }
+ }
+ else {
+ if (alertNetwork === true) {
+ CIRCLES.getCirclesWebsocket().emit(CIRCLES.EVENTS.OBJECT_NETWORKED_ATTACHED, CONTEXT_AF.getNetworkDataObject() );
+ }
+ CONTEXT_AF.removeEventListeners();
+ }
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, networkReadyFunc);
+ };
+
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ networkReadyFunc();
+ }
+ else {
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, networkReadyFunc);
+ }
+
+ CONTEXT_AF.data.networkedEnabled = enable;
+ },
+ showThisElement: function (isShowing, alertNetwork) {
+ //console.log('showThisElement', this.el.id, isShowing, alertNetwork);
+
+ this.isShowing = isShowing;
+
+ this.enableNetworking(isShowing, alertNetwork);
+ // this.el.setAttribute('circles-networked-basic', {networkedEnabled:isShowing});
+ this.el.setAttribute('circles-interactive-visible', isShowing);
+
+ if (this.el.components['circles-artefact']) {
+ this.el.components['circles-artefact'].removeLabelEventListener();
+ if (isShowing) {
+ this.el.components['circles-artefact'].addLabelEventListener();
+ }
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/components/circles-object-world.js b/src/components/circles-object-world.js
index f70b1930..7fb6b2d0 100644
--- a/src/components/circles-object-world.js
+++ b/src/components/circles-object-world.js
@@ -16,6 +16,10 @@ schema: {
CONTEXT_AF.el.setAttribute('circles-object-world', {world:CIRCLES.getCirclesWorldName()});
}
if (CONTEXT_AF.data.id === '') {
+ if (!CONTEXT_AF.el.id) {
+ console.error('[circles-object-world]: A networked object requires an ID.')
+ }
+
CONTEXT_AF.el.setAttribute('circles-object-world', {id:CONTEXT_AF.el.id});
}
diff --git a/src/components/circles-pickup-networked.js b/src/components/circles-pickup-networked.js
index 4bb5f83f..46236d0d 100644
--- a/src/components/circles-pickup-networked.js
+++ b/src/components/circles-pickup-networked.js
@@ -46,6 +46,16 @@ AFRAME.registerComponent('circles-pickup-networked', {
}
CONTEXT_AF.origId = CONTEXT_AF.el.components['circles-object-world'].data.id
+
+ //want to make sure clone's label clicks into artefact
+ if (CONTEXT_AF.isClone === true) {
+ //make sure label click works on networked elements (if artefact)
+ const labelEl = document.querySelector('#' + CONTEXT_AF.origId + '_label');
+
+ if (labelEl) {
+ labelEl.querySelector('.label_bg').addEventListener('click', CONTEXT_AF.clickLabelFunc);
+ }
+ }
},
update : function(oldData) {
const CONTEXT_AF = this;
@@ -232,17 +242,19 @@ AFRAME.registerComponent('circles-pickup-networked', {
CONTEXT_AF.networkAttachedFunc = function(data) {
//console.log('networkAttachedFunc', CONTEXT_AF.el.id);
- const isSameWorld = (data.world === CIRCLES.getCirclesWorldName());
- const isSameElem = (data.origId === CONTEXT_AF.origId);
- if (isSameWorld && isSameElem) {
- if (CONTEXT_AF.isClone === true) {
- //make sure label click works on networked elements (if artefact)
- const labelEl = document.querySelector('#' + CONTEXT_AF.origId + '_label');
- if (labelEl) {
- labelEl.querySelector('.label_bg').addEventListener('click', CONTEXT_AF.clickLabelFunc);
- }
- }
- }
+ // const isSameWorld = (data.world === CIRCLES.getCirclesWorldName());
+ // const isSameElem = (data.origId === CONTEXT_AF.origId);
+
+ // if (isSameWorld && isSameElem) {
+ // if (CONTEXT_AF.isClone === true) {
+ // //make sure label click works on networked elements (if artefact)
+ // const labelEl = document.querySelector('#' + CONTEXT_AF.origId + '_label');
+
+ // if (labelEl) {
+ // labelEl.querySelector('.label_bg').addEventListener('click', CONTEXT_AF.clickLabelFunc);
+ // }
+ // }
+ // }
};
CONTEXT_AF.networkDetachedFunc = function(data) {
@@ -280,7 +292,11 @@ AFRAME.registerComponent('circles-pickup-networked', {
document.body.addEventListener('entityCreated', function(e) {
//console.log('NAF entityCreated', e.detail.el);
- if (CONTEXT_AF.isClone === false) {
+ if (!e.detail.el.components['circles-object-world']) {
+ return;
+ }
+
+ if (CONTEXT_AF.isClone === false && e.detail.el.components['circles-object-world'].data.id === CONTEXT_AF.origId) {
CONTEXT_AF.initSyncObjects();
}
});
@@ -402,12 +418,8 @@ AFRAME.registerComponent('circles-pickup-networked', {
//you are now the host/owner of this networked object
CONTEXT_AF.showThisElement(true, true);
- console.log(CONTEXT_AF.lastKnowObjectData);
-
if (CONTEXT_AF.lastKnowObjectData) {
//determine last state and set this new one to a similar one
- console.log(CONTEXT_AF.lastKnowObjectData.circlesObjectWorld.pickedup);
-
if (CONTEXT_AF.lastKnowObjectData.circlesObjectWorld.pickedup === true) {
//pick up
CONTEXT_AF.el.components['circles-pickup-object'].pickup(true, CONTEXT_AF.el.components['circles-pickup-object']);
diff --git a/src/components/index.js b/src/components/index.js
index 7fea4629..f871a8e3 100755
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -16,6 +16,7 @@ require('./circles-material-extend-fresnel');
require('./circles-material-override');
require('./circles-label');
require('./circles-lookat');
+require('./circles-networked-basic');
require('./circles-object-world');
require('./circles-parent-constraint');
require('./circles-pdf-loader');
diff --git a/src/core/circles_framework.js b/src/core/circles_framework.js
index f8fb405f..c3dcdf47 100755
--- a/src/core/circles_framework.js
+++ b/src/core/circles_framework.js
@@ -126,6 +126,7 @@ const EVENTS = {
const NETWORKED_TEMPLATES = {
AVATAR : 'circles-user-template',
INTERACTIVE_OBJECT : 'circles-interactive-object-template',
+ BASIC_OBJECT : 'circles-basic-object-template',
ARTEFACT : 'circles-artefact-template',
TEXT : 'circles-text-template'
};
diff --git a/src/webpack.worlds.parts/circles_assets.part.html b/src/webpack.worlds.parts/circles_assets.part.html
index e5c08c45..29dfa918 100644
--- a/src/webpack.worlds.parts/circles_assets.part.html
+++ b/src/webpack.worlds.parts/circles_assets.part.html
@@ -52,6 +52,11 @@
+
+
+
+
+
diff --git a/src/webpack.worlds.parts/circles_end_scripts.part.html b/src/webpack.worlds.parts/circles_end_scripts.part.html
index e114d51c..3f33df59 100644
--- a/src/webpack.worlds.parts/circles_end_scripts.part.html
+++ b/src/webpack.worlds.parts/circles_end_scripts.part.html
@@ -151,6 +151,32 @@
]
});
+ NAF.schemas.add({
+ template: '#' + CIRCLES.NETWORKED_TEMPLATES.BASIC_OBJECT,
+ components: [
+ 'class',
+ 'position',
+ 'rotation',
+ 'scale',
+ 'gltf-model',
+ 'geometry',
+ 'material',
+ 'obj-model',
+ 'text',
+ 'circles-object-world',
+ 'circles-interactive-object',
+ //'circles-interactive-visible', //want this hideen if released in another world ...
+ //'circles-pickup-object',
+ 'circles-networked-basic',
+ 'shadow',
+ //'class'
+ // {
+ // selector: '.interactive',
+ // component: 'gltf-model',
+ // },
+ ]
+ });
+
NAF.schemas.add({
template: '#' + CIRCLES.NETWORKED_TEMPLATES.ARTEFACT,
components: [
diff --git a/src/worlds/Campfire/scripts/campfire-interactive.js b/src/worlds/Campfire/scripts/campfire-interactive.js
index 1d2e9ead..9bad65fb 100644
--- a/src/worlds/Campfire/scripts/campfire-interactive.js
+++ b/src/worlds/Campfire/scripts/campfire-interactive.js
@@ -59,7 +59,8 @@ AFRAME.registerComponent('campfire-interactive', {
CONTEXT_AF.socket = null;
CONTEXT_AF.connected = false;
CONTEXT_AF.campfireEventName = "campfire_event";
- CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, function (data) {
+
+ CONTEXT_AF.createNetworkingSystem = function () {
CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
CONTEXT_AF.connected = true;
console.warn("messaging system connected at socket: " + CONTEXT_AF.socket.id + " in room:" + CIRCLES.getCirclesGroupName() + ' in world:' + CIRCLES.getCirclesWorldName());
@@ -97,7 +98,19 @@ AFRAME.registerComponent('campfire-interactive', {
CONTEXT_AF.fireOn = data.campfireON;
}
});
- });
+ };
+
+ //check if circle networking is ready. If not, add an eent to listen for when it is ...
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ CONTEXT_AF.createNetworkingSystem();
+ }
+ else {
+ const wsReadyFunc = function() {
+ CONTEXT_AF.createNetworkingSystem();
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ };
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ }
},
update() {},
turnFire : function (turnOn) {
diff --git a/src/worlds/ExampleNetworking/index.html b/src/worlds/ExampleNetworking/index.html
new file mode 100644
index 00000000..8da3b641
--- /dev/null
+++ b/src/worlds/ExampleNetworking/index.html
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/worlds/Network_TestSpace/profile.jpg b/src/worlds/ExampleNetworking/profile.jpg
similarity index 100%
rename from src/worlds/Network_TestSpace/profile.jpg
rename to src/worlds/ExampleNetworking/profile.jpg
diff --git a/src/worlds/ExampleNetworking/scripts/robot-controls.js b/src/worlds/ExampleNetworking/scripts/robot-controls.js
new file mode 100644
index 00000000..2a2c2926
--- /dev/null
+++ b/src/worlds/ExampleNetworking/scripts/robot-controls.js
@@ -0,0 +1,176 @@
+
+AFRAME.registerComponent('robot-controls', {
+ schema: {
+ rotationIncrementRad: {type:'number', default:0.03}, //radians
+ rotationIntervalMS: {type:'number', default:20}, //ms (how fast this moves on button press)
+ },
+ init() {
+ const CONTEXT_AF = this;
+ CONTEXT_AF.connected = false;
+ CONTEXT_AF.controlsNetworkEventName = 'controls-network-event-name';
+ CONTEXT_AF.isMouseDown = false;
+
+ CONTEXT_AF.createNetworkingSystem = function () {
+ CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
+ CONTEXT_AF.connected = true;
+ console.warn("messaging system connected at socket: " + CONTEXT_AF.socket.id + " in room:" + CIRCLES.getCirclesGroupName() + ' in world:' + CIRCLES.getCirclesWorldName());
+
+ //listen for when others turn on campfire
+ CONTEXT_AF.socket.on(CONTEXT_AF.controlsNetworkEventName, function(data) {
+ //capture new rotations
+ //shoulderOverBackAmt, shoulderLeftRightAmt, elbowOverBackAmt, elbowLeftRightAmt, room, world
+ CONTEXT_AF.updateRobotParts(data.shoulderOverBackAmt, data.shoulderLeftRightAmt, data.elbowOverBackAmt, data.elbowLeftRightAmt, true);
+ });
+ };
+
+ //check if circle networking is ready. If not, add an eent to listen for when it is ...
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ CONTEXT_AF.createNetworkingSystem();
+ }
+ else {
+ const wsReadyFunc = function() {
+ CONTEXT_AF.createNetworkingSystem();
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ };
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ }
+
+ CONTEXT_AF.createButtonAndRobotConnections();
+ },
+ update(oldData) {
+ const CONTEXT_AF = this;
+ const data = this.data;
+
+ if (Object.keys(data).length === 0) { return; } // No need to update. as nothing here yet
+
+ if ( (oldData.rotationIntervalMS !== data.rotationIntervalMS) && (data.rotationIntervalMS !== '') ) {
+ // Set up the tick throttling.
+ CONTEXT_AF.tick = AFRAME.utils.throttleTick(CONTEXT_AF.tick, data.rotationIntervalMS, CONTEXT_AF);
+ }
+ },
+ // remove() {},
+ tick(time, timeDelta) {
+ this.updateRobotParts(this.rotateShoulder_OverBack_Amt, this.rotateShoulder_LeftRight_Amt, this.rotateElbow_OverBack_Amt, this.rotateElbow_LeftRight_Amt, true);
+
+ // we will send event over network that buttons are being pressed so that everything synchs up (and both clients can move the robot arm)
+ // this event will not be sent to itself so this will only go to the "other" client to synch. We still want to move the "invisible" networked parts
+ // so if one client drops we are still at the same spot
+ if (this.connected === true && this.isMouseDown === true) { //don't want this firing unless mouse is pressed
+ this.socket.emit(this.controlsNetworkEventName, { shoulderOverBackAmt: this.rotateShoulder_OverBack_Amt,
+ shoulderLeftRightAmt: this.rotateShoulder_LeftRight_Amt,
+ elbowOverBackAmt: this.rotateElbow_OverBack_Amt,
+ elbowLeftRightAmt: this.rotateElbow_LeftRight_Amt,
+ room:CIRCLES.getCirclesGroupName(), world:CIRCLES.getCirclesWorldName()
+ });
+ }
+ },
+ updateRobotParts: function(shoulderOverBackAmt, shoulderLeftRightAmt, elbowOverBackAmt, elbowLeftRightAmt, updateDisplays) {
+ //adjust rotation
+ this.robotShoulder_overback.object3D.rotation.x += shoulderOverBackAmt;
+ this.robotShoulder_leftright.object3D.rotation.y += shoulderLeftRightAmt;
+ this.robotElbow_overback.object3D.rotation.x += elbowOverBackAmt;
+ this.robotElbow_leftright.object3D.rotation.y += elbowLeftRightAmt;
+
+ //adjust displays
+ //Elbow\n\nX-Rot:00\nY-Rot:00
+ if (updateDisplays === true) {
+ if (this.shoulderDisplayElem) {
+ this.shoulderDisplayElem.setAttribute( 'text', {value:'Shoulder\n\nX-Rot: ' + Math.floor(THREE.MathUtils.radToDeg(this.robotShoulder_overback.object3D.rotation.x)) +
+ '\nY-Rot: ' + Math.floor(THREE.MathUtils.radToDeg(this.robotShoulder_leftright.object3D.rotation.y))});
+ }
+
+ if (this.elbowDisplayElem) {
+ this.elbowDisplayElem.setAttribute( 'text', {value:'Elbow\n\nX-Rot: ' + Math.floor(THREE.MathUtils.radToDeg(this.robotElbow_overback.object3D.rotation.x)) +
+ '\nY-Rot: ' + Math.floor(THREE.MathUtils.radToDeg(this.robotElbow_leftright.object3D.rotation.y))});
+ }
+ }
+ },
+ createButtonAndRobotConnections: function() {
+ const CONTEXT_AF = this;
+ CONTEXT_AF.rotateShoulder_OverBack_Amt = 0.0;
+ CONTEXT_AF.rotateShoulder_LeftRight_Amt = 0.0;
+ CONTEXT_AF.rotateElbow_OverBack_Amt = 0.0;
+ CONTEXT_AF.rotateElbow_LeftRight_Amt = 0.0;
+
+ //jointType: ['shoulder', 'elbow']
+ //rotType: ['overback', 'leftright']
+ CONTEXT_AF.rotateElem = function(jointType, rotType, angRad) {
+ if (rotType === CONTEXT_AF.ROT_TYPE.OVER_BACK) {
+ if (jointType === CONTEXT_AF.JOINT_TYPE.SHOULDER) {
+ CONTEXT_AF.rotateShoulder_OverBack_Amt = angRad;
+ }
+ else if (jointType === CONTEXT_AF.JOINT_TYPE.ELBOW) {
+ CONTEXT_AF.rotateElbow_OverBack_Amt = angRad;
+ }
+ }
+ else if (rotType === CONTEXT_AF.ROT_TYPE.LEFT_RIGHT) {
+ if (jointType === CONTEXT_AF.JOINT_TYPE.SHOULDER) {
+ CONTEXT_AF.rotateShoulder_LeftRight_Amt = angRad;
+ }
+ else if (jointType === CONTEXT_AF.JOINT_TYPE.ELBOW) {
+ CONTEXT_AF.rotateElbow_LeftRight_Amt = angRad;
+ }
+ }
+ }
+
+ CONTEXT_AF.robot_arm = document.querySelector('#robot_arm');
+ CONTEXT_AF.robotShoulder_leftright = robot_arm.querySelector('.pivot.shoulder.left.right');
+ CONTEXT_AF.robotShoulder_overback = robot_arm.querySelector('.pivot.shoulder.over.back');
+ CONTEXT_AF.robotElbow_leftright = robot_arm.querySelector('.pivot.elbow.left.right');
+ CONTEXT_AF.robotElbow_overback = robot_arm.querySelector('.pivot.elbow.over.back');
+
+ //get elem refs
+ CONTEXT_AF.robot_controls = document.querySelector('#robot_controls');
+ CONTEXT_AF.shoulderControls = {
+ overButton: CONTEXT_AF.robot_controls.querySelector('.shoulder > .over'),
+ backButton: CONTEXT_AF.robot_controls.querySelector('.shoulder > .back'),
+ leftButton: CONTEXT_AF.robot_controls.querySelector('.shoulder > .left'),
+ rightButton: CONTEXT_AF.robot_controls.querySelector('.shoulder > .right')
+ };
+ CONTEXT_AF.elbowControls = {
+ overButton: CONTEXT_AF.robot_controls.querySelector('.elbow > .over'),
+ backButton: CONTEXT_AF.robot_controls.querySelector('.elbow > .back'),
+ leftButton: CONTEXT_AF.robot_controls.querySelector('.elbow > .left'),
+ rightButton: CONTEXT_AF.robot_controls.querySelector('.elbow > .right')
+ };
+
+ CONTEXT_AF.shoulderDisplayElem = CONTEXT_AF.robot_controls.querySelector('#display_shoulder');
+ CONTEXT_AF.elbowDisplayElem = CONTEXT_AF.robot_controls.querySelector('#display_elbow');
+
+ CONTEXT_AF.ROT_TYPE = {
+ OVER_BACK: 'overback',
+ LEFT_RIGHT: 'leftright',
+ };
+
+ CONTEXT_AF.JOINT_TYPE = {
+ SHOULDER: 'shoulder',
+ ELBOW: 'elbow',
+ };
+
+ //animate shoulder
+ CONTEXT_AF.shoulderControls.overButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.OVER_BACK, CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.shoulderControls.overButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.OVER_BACK, 0.0); });
+
+ CONTEXT_AF.shoulderControls.backButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.OVER_BACK, -CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.shoulderControls.backButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.OVER_BACK, 0.0); });
+
+ CONTEXT_AF.shoulderControls.leftButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, -CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.shoulderControls.leftButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, 0.0); });
+
+ CONTEXT_AF.shoulderControls.rightButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.shoulderControls.rightButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.SHOULDER, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, 0.0); });
+
+ //animate elbow
+ CONTEXT_AF.elbowControls.overButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.OVER_BACK, CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.elbowControls.overButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.OVER_BACK, 0.0); });
+
+ CONTEXT_AF.elbowControls.backButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.OVER_BACK, -CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.elbowControls.backButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.OVER_BACK, 0.0); });
+
+ CONTEXT_AF.elbowControls.leftButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, -CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.elbowControls.leftButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, 0.0); });
+
+ CONTEXT_AF.elbowControls.rightButton.addEventListener('mousedown', function() { CONTEXT_AF.isMouseDown = true; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, CONTEXT_AF.data.rotationIncrementRad); });
+ CONTEXT_AF.elbowControls.rightButton.addEventListener('mouseup', function() { CONTEXT_AF.isMouseDown = false; CONTEXT_AF.rotateElem(CONTEXT_AF.JOINT_TYPE.ELBOW, CONTEXT_AF.ROT_TYPE.LEFT_RIGHT, 0.0); });
+ }
+});
\ No newline at end of file
diff --git a/src/worlds/Network_TestSpace/settings.JSON b/src/worlds/ExampleNetworking/settings.JSON
similarity index 100%
rename from src/worlds/Network_TestSpace/settings.JSON
rename to src/worlds/ExampleNetworking/settings.JSON
diff --git a/src/worlds/ExampleWorld/js/lights-interaction.js b/src/worlds/ExampleWorld/js/lights-interaction.js
index 3eb47ce1..2b3cbec5 100644
--- a/src/worlds/ExampleWorld/js/lights-interaction.js
+++ b/src/worlds/ExampleWorld/js/lights-interaction.js
@@ -4,13 +4,6 @@ AFRAME.registerComponent('lights-interactive', {
const CONTEXT_AF = this;
const scene = CIRCLES.getCirclesSceneElement();
- scene.addEventListener(CIRCLES.EVENTS.READY, function() {
- console.log('Circles is ready: ' + CIRCLES.isReady());
-
- //this is the camera that is now also ready, if we want to parent elements to it i.e., a user interface or 2D buttons
- console.log("Circles camera ID: " + CIRCLES.getMainCameraElement().id);
- });
-
//have to capture all components we need to play with here
CONTEXT_AF.light_1 = scene.querySelector('#light_1');
CONTEXT_AF.light_2 = scene.querySelector('#light_2');
@@ -28,7 +21,7 @@ AFRAME.registerComponent('lights-interactive', {
CONTEXT_AF.connected = false;
CONTEXT_AF.synchEventName = "lights_event";
- CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, function (data) {
+ CONTEXT_AF.createNetworkingSystem = function () {
CONTEXT_AF.socket = CIRCLES.getCirclesWebsocket();
CONTEXT_AF.connected = true;
console.warn("messaging system connected at socket: " + CONTEXT_AF.socket.id + " in room:" + CIRCLES.getCirclesGroupName() + ' in world:' + CIRCLES.getCirclesWorldName());
@@ -128,7 +121,26 @@ AFRAME.registerComponent('lights-interactive', {
}
}
});
+ };
+
+ scene.addEventListener(CIRCLES.EVENTS.READY, function() {
+ console.log('Circles is ready: ' + CIRCLES.isReady());
+
+ //this is the camera that is now also ready, if we want to parent elements to it i.e., a user interface or 2D buttons
+ console.log("Circles camera ID: " + CIRCLES.getMainCameraElement().id);
});
+
+ //check if circle networking is ready. If not, add an eent to listen for when it is ...
+ if (CIRCLES.isCirclesWebsocketReady()) {
+ CONTEXT_AF.createNetworkingSystem();
+ }
+ else {
+ const wsReadyFunc = function() {
+ CONTEXT_AF.createNetworkingSystem();
+ CONTEXT_AF.el.sceneEl.removeEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ };
+ CONTEXT_AF.el.sceneEl.addEventListener(CIRCLES.EVENTS.WS_CONNECTED, wsReadyFunc);
+ }
},
update() {},
toggleLight : function (lightElem, playSound) {
diff --git a/src/worlds/Network_TestSpace/index.html b/src/worlds/Network_TestSpace/index.html
deleted file mode 100644
index ec3b9848..00000000
--- a/src/worlds/Network_TestSpace/index.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/worlds/Network_TestSpace/scripts/script.js b/src/worlds/Network_TestSpace/scripts/script.js
deleted file mode 100644
index 6aba3e04..00000000
--- a/src/worlds/Network_TestSpace/scripts/script.js
+++ /dev/null
@@ -1,18 +0,0 @@
-
-AFRAME.registerComponent('test', {
- schema: {
- particles: {type:'number', default:1.0},
- },
- init() {
- const CONTEXT_AF = this;
- const DATA = CONTEXT_AF.data;
- },
- update() {
- const CONTEXT_AF = this;
- const data = this.data;
-
- if (Object.keys(data).length === 0) { return; } // No need to update. as nothing here yet
- },
- remove() {},
- tick(time, timeDelta) {},
-});
\ No newline at end of file