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 @@ + +