matrix/trystero plugin updates + added simple example
This commit is contained in:
parent
b07e38db6e
commit
ead6a93171
26 changed files with 135 additions and 37890 deletions
Binary file not shown.
|
|
@ -1,262 +0,0 @@
|
|||
{
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 3,
|
||||
"max" : [
|
||||
2.000000
|
||||
],
|
||||
"min" : [
|
||||
0.000000
|
||||
],
|
||||
"type" : "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 3,
|
||||
"max" : [
|
||||
0.000000,
|
||||
1.000000,
|
||||
0.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
0.000000,
|
||||
-8.742278e-008,
|
||||
0.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView" : 2,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
35
|
||||
],
|
||||
"min" : [
|
||||
0
|
||||
],
|
||||
"type" : "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView" : 3,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000,
|
||||
1.000001
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 4,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 5,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
-0.000000,
|
||||
-0.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
0.000000,
|
||||
-0.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView" : 6,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC2"
|
||||
}
|
||||
],
|
||||
"animations" : [
|
||||
{
|
||||
"channels" : [
|
||||
{
|
||||
"sampler" : 0,
|
||||
"target" : {
|
||||
"node" : 0,
|
||||
"path" : "rotation"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name" : "animation_AnimatedCube",
|
||||
"samplers" : [
|
||||
{
|
||||
"input" : 0,
|
||||
"interpolation" : "LINEAR",
|
||||
"output" : 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"asset" : {
|
||||
"generator" : "VKTS glTF 2.0 exporter",
|
||||
"version" : "2.0"
|
||||
},
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 12,
|
||||
"byteOffset" : 0
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 48,
|
||||
"byteOffset" : 12
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 72,
|
||||
"byteOffset" : 60,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 432,
|
||||
"byteOffset" : 132,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 432,
|
||||
"byteOffset" : 564,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 576,
|
||||
"byteOffset" : 996,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 288,
|
||||
"byteOffset" : 1572,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"buffers" : [
|
||||
{
|
||||
"byteLength" : 1860,
|
||||
"uri" : "AnimatedCube.bin"
|
||||
}
|
||||
],
|
||||
"images" : [
|
||||
{
|
||||
"uri" : "AnimatedCube_BaseColor.png"
|
||||
},
|
||||
{
|
||||
"uri" : "AnimatedCube_MetallicRoughness.png"
|
||||
}
|
||||
],
|
||||
"materials" : [
|
||||
{
|
||||
"name" : "AnimatedCube",
|
||||
"pbrMetallicRoughness" : {
|
||||
"baseColorTexture" : {
|
||||
"index" : 0
|
||||
},
|
||||
"metallicRoughnessTexture" : {
|
||||
"index" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes" : [
|
||||
{
|
||||
"name" : "AnimatedCube",
|
||||
"primitives" : [
|
||||
{
|
||||
"attributes" : {
|
||||
"NORMAL" : 4,
|
||||
"POSITION" : 3,
|
||||
"TANGENT" : 5,
|
||||
"TEXCOORD_0" : 6
|
||||
},
|
||||
"indices" : 2,
|
||||
"material" : 0,
|
||||
"mode" : 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"mesh" : 0,
|
||||
"name" : "AnimatedCube",
|
||||
"rotation" : [
|
||||
0.000000,
|
||||
-1.000000,
|
||||
0.000000,
|
||||
0.000000
|
||||
]
|
||||
}
|
||||
],
|
||||
"samplers" : [
|
||||
{}
|
||||
],
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures" : [
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 0
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v3.5.30",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"AnimatedCube"
|
||||
}
|
||||
],
|
||||
"animations":[
|
||||
{
|
||||
"channels":[
|
||||
{
|
||||
"sampler":0,
|
||||
"target":{
|
||||
"node":0,
|
||||
"path":"rotation"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name":"walk",
|
||||
"samplers":[
|
||||
{
|
||||
"input":4,
|
||||
"interpolation":"LINEAR",
|
||||
"output":5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"materials":[
|
||||
{
|
||||
"name":"AnimatedCube",
|
||||
"pbrMetallicRoughness":{}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"AnimatedCube",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"TEXCOORD_0":1,
|
||||
"NORMAL":2
|
||||
},
|
||||
"indices":3,
|
||||
"material":0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":36,
|
||||
"max":[
|
||||
1,
|
||||
1,
|
||||
1.0000009536743164
|
||||
],
|
||||
"min":[
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":36,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":36,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":36,
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":4,
|
||||
"componentType":5126,
|
||||
"count":3,
|
||||
"max":[
|
||||
2
|
||||
],
|
||||
"min":[
|
||||
0
|
||||
],
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":5,
|
||||
"componentType":5126,
|
||||
"count":3,
|
||||
"type":"VEC4"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":432,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":432,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":432,
|
||||
"byteOffset":720,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":72,
|
||||
"byteOffset":1152,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":12,
|
||||
"byteOffset":1224
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":48,
|
||||
"byteOffset":1236
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":1284,
|
||||
"uri":"data:application/octet-stream;base64,AACAPwAAgL8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAvwAAgD8AAIC/7/9/PwAAgD8IAIA/AACAPwAAgD/v/3+/AACAPwAAgD/v/3+/AACAPwAAgL8AAIA/AACAPwAAgL8AAIC/7/9/PwAAgD8IAIA/AACAvwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAvwAAgD8AAIC/AACAPwAAgD/v/3+/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIA/7/9/PwAAgD8IAIA/AACAPwAAgD/v/3+/7/9/PwAAgD8IAIA/AACAPwAAgL8AAIA/7/9/PwAAgD8IAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAPwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAgD8AAAAAAACAPwAAAAAAAAAAAACAvwAAgD8AAIC/AACAPwAAAAAAAACAAACAvwAAgD8AAIC/AAAAAAAAAAAAAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAIC/AACAPwAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgL8AAIA/AAAAAAAAAAAAAACAAACAvwAAgD8AAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAIAAAIC/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/AACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAgAAAAAAAAIA/AAAAgAAAAAAAAIA/AAAAgAAAAAAAAIA/AACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAAAAAAAAAgD8AAABAAAAAAAAAAAAAAACAAACAPwAAAIAAAIC/AAAAAC69OzMAAAAALr27MwAAAIAAAIA/"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
BIN
example/assets/example.blend
Normal file
BIN
example/assets/example.blend
Normal file
Binary file not shown.
BIN
example/assets/example.glb
Normal file
BIN
example/assets/example.glb
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,11 +1,12 @@
|
|||
chatComponent = {
|
||||
|
||||
html: `
|
||||
<div id="chat">
|
||||
<div id="videos" style="pointer-events:none"></div>
|
||||
<div id="messages" aria-live="assertive" aria-relevant></div>
|
||||
<div id="chatfooter">
|
||||
<div id="chatbar">
|
||||
<input id="chatline" type="text" placeholder="type here"></input>
|
||||
<input id="chatline" type="text" placeholder="chat here"></input>
|
||||
</div>
|
||||
<button id="showchat" class="btn">show chat</button>
|
||||
</div>
|
||||
|
|
@ -16,8 +17,8 @@ chatComponent = {
|
|||
|
||||
scene: null,
|
||||
visible: true,
|
||||
visibleChatbar: false,
|
||||
messages: [],
|
||||
oneMessagePerUser: false,
|
||||
|
||||
username: '', // configured by 'network.connected' event
|
||||
|
||||
|
|
@ -29,10 +30,10 @@ chatComponent = {
|
|||
install(opts){
|
||||
this.opts = opts
|
||||
this.scene = opts.scene
|
||||
this.$chatbar.style.display = 'none'
|
||||
el.className = "xrf"
|
||||
el.style.display = 'none' // start hidden
|
||||
document.body.appendChild( el )
|
||||
this.visibleChatbar = false
|
||||
document.dispatchEvent( new CustomEvent("$chat:ready", {detail: opts}) )
|
||||
this.send({message:`Welcome to <b>${document.location.search.substr(1)}</b>, a 3D scene(file) which simply links to other ones.<br>You can start a solo offline exploration in XR right away.<br>Type /help below, or use the arrow- or WASD-keys on your keyboard, and mouse-drag to rotate.<br>`, class: ["info","guide","multiline"] })
|
||||
},
|
||||
|
|
@ -41,6 +42,7 @@ chatComponent = {
|
|||
let {$chatline} = this
|
||||
|
||||
$chatline.addEventListener('click', (e) => this.inform() )
|
||||
|
||||
$chatline.addEventListener('keydown', (e) => {
|
||||
if (e.key == 'Enter' ){
|
||||
if( $chatline.value[0] != '/' ){
|
||||
|
|
@ -52,16 +54,20 @@ chatComponent = {
|
|||
}
|
||||
})
|
||||
|
||||
document.addEventListener('network.connect', (e) => {
|
||||
this.visible = true
|
||||
this.$chatbar.style.display = '' // show
|
||||
})
|
||||
|
||||
document.addEventListener('network.connected', (e) => {
|
||||
if( e.detail.username ) this.username = e.detail.username
|
||||
})
|
||||
|
||||
console.dir(this.scene)
|
||||
},
|
||||
|
||||
inform(){
|
||||
if( !this.inform.informed && (this.inform.informed = true) ){
|
||||
window.notify("Here you can update your statusline.<br>Protocols like [Matrix] allow you to view the full transcript<br>in a dedicated client like <a href='https://element.io' target='_blank'>element.io</a>")
|
||||
window.notify("Connected via P2P. You can now type message which will be visible to others.")
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -83,6 +89,7 @@ chatComponent = {
|
|||
let {$messages} = this
|
||||
opts = { linebreak:true, message:"", class:[], ...opts }
|
||||
if( window.frontend && window.frontend.emit ) window.frontend.emit('$chat.send', opts )
|
||||
opts.pos = opts.pos || network.posName || network.pos
|
||||
let div = document.createElement('div')
|
||||
let msg = document.createElement('div')
|
||||
let br = document.createElement('br')
|
||||
|
|
@ -98,9 +105,9 @@ chatComponent = {
|
|||
br.classList.add.apply(br.classList, opts.class)
|
||||
div.classList.add.apply(div.classList, opts.class.concat(["envelope"]))
|
||||
}
|
||||
if( !opts.from && !msg.className.match(/(info|guide)/) ){
|
||||
if( !msg.className.match(/(info|guide|ui)/) ){
|
||||
let frag = xrf.URI.parse(document.location.hash)
|
||||
opts.from = this.username
|
||||
opts.from = 'you'
|
||||
if( frag.pos ) opts.pos = frag.pos.string
|
||||
msg.classList.add('self')
|
||||
}
|
||||
|
|
@ -116,7 +123,7 @@ chatComponent = {
|
|||
}
|
||||
div.appendChild(msg)
|
||||
// force one message per user
|
||||
if( opts.from ){
|
||||
if( this.oneMessagePerUser && opts.from ){
|
||||
div.id = this.hyphenate(opts.from)
|
||||
let oldMsg = $messages.querySelector(`#${div.id}`)
|
||||
if( oldMsg ) oldMsg.remove()
|
||||
|
|
@ -148,9 +155,6 @@ chatComponent = {
|
|||
if( !el.inited && (el.inited = true) ) me.initListeners()
|
||||
break;
|
||||
}
|
||||
case "visibleChatbar": {
|
||||
me.$chatbar.style.display = v ? 'block' : 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,25 +238,25 @@ chatComponent.css = `
|
|||
max-width:unset;
|
||||
}
|
||||
#messages{
|
||||
/*
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
flex-direction: column;
|
||||
width: 91%;
|
||||
max-width: 500px;
|
||||
*/
|
||||
width:100%;
|
||||
align-items: flex-start;
|
||||
position: absolute;
|
||||
transition:1s;
|
||||
top: 0px;
|
||||
top: 77px;
|
||||
left: 0;
|
||||
bottom: 49px;
|
||||
padding: 20px;
|
||||
overflow:hidden;
|
||||
overflow-y: scroll;
|
||||
pointer-events:none;
|
||||
transition:1s;
|
||||
width: 91%;
|
||||
max-width: 500px;
|
||||
z-index: 100;
|
||||
-webkit-user-select:none;
|
||||
-moz-user-select:-moz-none;
|
||||
-ms-user-select:none;
|
||||
user-select:none;
|
||||
}
|
||||
body.menu #messages{
|
||||
top:50px;
|
||||
|
|
@ -261,7 +265,11 @@ chatComponent.css = `
|
|||
pointer-events:all;
|
||||
}
|
||||
#messages *{
|
||||
pointer-events:all;
|
||||
pointer-events:none;
|
||||
-webkit-user-select:none;
|
||||
-moz-user-select:-moz-none;
|
||||
-ms-user-select:none;
|
||||
user-select:none;
|
||||
}
|
||||
#messages .msg{
|
||||
transition:all 1s ease;
|
||||
|
|
@ -272,11 +280,18 @@ chatComponent.css = `
|
|||
color: #000c;
|
||||
margin-bottom: 10px;
|
||||
line-height:23px;
|
||||
pointer-events:visible;
|
||||
line-height:33px;
|
||||
cursor:grabbing;
|
||||
border: 1px solid #0002;
|
||||
}
|
||||
#messages .msg *{
|
||||
pointer-events:all;
|
||||
-webkit-user-select:text;
|
||||
-moz-user-select:-moz-text;
|
||||
-ms-user-select:text;
|
||||
user-select:text;
|
||||
}
|
||||
|
||||
#messages .msg.self{
|
||||
border-radius: 20px;
|
||||
background:var(--xrf-box-shadow);
|
||||
|
|
@ -303,7 +318,7 @@ chatComponent.css = `
|
|||
transition:0.3s;
|
||||
}
|
||||
#messages .msg.info a,
|
||||
#messages .ruler a{
|
||||
#messages a.ruler{
|
||||
color:#FFF;
|
||||
}
|
||||
#messages .msg a:hover{
|
||||
|
|
@ -375,10 +390,19 @@ chatComponent.css = `
|
|||
margin:0;
|
||||
}
|
||||
|
||||
.envelope{
|
||||
height:unset;
|
||||
.envelope,
|
||||
.envelope * {
|
||||
overflow:hidden;
|
||||
transition:1s;
|
||||
pointer-events:none;
|
||||
}
|
||||
.envelope a,
|
||||
.envelope button,
|
||||
.envelope input,
|
||||
.envelope textarea,
|
||||
.envelope msg,
|
||||
.envelope msg * {
|
||||
pointer-events:all;
|
||||
}
|
||||
|
||||
.user{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ connectionsComponent = {
|
|||
|
||||
html: `
|
||||
<div id="connections">
|
||||
<i class="gg-close-o" id="close" onclick="$connections.toggle()"></i>
|
||||
<i class="gg-close-o" id="close" onclick="$connections.visible = false"></i>
|
||||
<br>
|
||||
<div class="tab-frame">
|
||||
<input type="radio" name="tab" id="login" checked>
|
||||
|
|
@ -83,6 +83,8 @@ connectionsComponent = {
|
|||
|
||||
init: (el) => new Proxy({
|
||||
|
||||
visible: true,
|
||||
|
||||
webcam: [{profile:{name:"No thanks"},config: () => document.createElement('div')}],
|
||||
chatnetwork: [{profile:{name:"No thanks"},config: () => document.createElement('div')}],
|
||||
scene: [{profile:{name:"No thanks"},config: () => document.createElement('div')}],
|
||||
|
|
@ -117,8 +119,7 @@ connectionsComponent = {
|
|||
},
|
||||
|
||||
toggle(){
|
||||
let parent = el.closest('.envelope')
|
||||
parent.style.display = parent.style.display == 'none' ? parent.style.display = '' : 'none'
|
||||
$chat.visible = !$chat.visible
|
||||
},
|
||||
|
||||
change(id,e){
|
||||
|
|
@ -130,13 +131,14 @@ connectionsComponent = {
|
|||
show(opts){
|
||||
opts = opts || {}
|
||||
if( opts.hide ){
|
||||
el.parentElement.parentElement.style.display = 'none'
|
||||
if( el.parentElement ) el.parentElement.parentElement.style.display = 'none' // hide along with wrapper elements
|
||||
if( !opts.showChat ) $chat.visible = false
|
||||
}else{
|
||||
$chat.visible = true
|
||||
this.visible = true
|
||||
// hide networking settings if entering thru meetinglink
|
||||
$networking.style.display = document.location.href.match(/meet=/) ? 'none' : 'block'
|
||||
if( !network.connected ){
|
||||
if( el.parentElement ) el.parentElement.parentElement.remove()
|
||||
document.querySelector('body > .xrf').appendChild(el)
|
||||
$chat.send({message:"", el, class:['ui']})
|
||||
if( !network.meetinglink ){ // set default
|
||||
|
|
@ -233,7 +235,7 @@ connectionsComponent = {
|
|||
reactToNetwork(){ // *TODO* move to network?
|
||||
|
||||
document.addEventListener('network.connect', () => {
|
||||
this.show({hide:true})
|
||||
this.show({hide:true, showChat: true})
|
||||
})
|
||||
document.addEventListener('network.disconnect', () => {
|
||||
this.connected = false
|
||||
|
|
@ -247,6 +249,7 @@ connectionsComponent = {
|
|||
set(data,k,v){
|
||||
data[k] = v
|
||||
switch( k ){
|
||||
case "visible": el.style.display = v ? '' : 'none'; break;
|
||||
case "webcam": $webcam.innerHTML = `<option>${data[k].map((p)=>p.profile.name).join('</option><option>')}</option>`; break;
|
||||
case "chatnetwork": $chatnetwork.innerHTML = `<option>${data[k].map((p)=>p.profile.name).join('</option><option>')}</option>`; break;
|
||||
case "scene": $scene.innerHTML = `<option>${data[k].map((p)=>p.profile.name).join('</option><option>')}</option>`; break;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ menuComponent = (el) => new Proxy({
|
|||
$buttons: $buttons = el.querySelector('#buttons'),
|
||||
$btnMore: $btnMore = el.querySelector('#more'),
|
||||
|
||||
toggle(){
|
||||
this.collapsed = !this.collapsed
|
||||
toggle(state){
|
||||
this.collapsed = state !== undefined ? state : !this.collapsed
|
||||
el.querySelector("i#icon").className = this.collapsed ? 'gg-close' : 'gg-menu'
|
||||
document.body.classList[ this.collapsed ? 'add' : 'remove' ](['menu'])
|
||||
},
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ window.frontend = (opts) => new Proxy({
|
|||
.setupUserHints()
|
||||
.setupNetworkListeners()
|
||||
.hidetopbarWhenMenuCollapse()
|
||||
.hideUIWhenNavigating()
|
||||
|
||||
window.notify = this.notify
|
||||
setTimeout( () => {
|
||||
|
|
@ -130,6 +131,29 @@ window.frontend = (opts) => new Proxy({
|
|||
return this
|
||||
},
|
||||
|
||||
hideUIWhenNavigating(){
|
||||
// hide ui when user is navigating the scene using mouse/touch
|
||||
let showUI = (show) => (e) => {
|
||||
let isChatMsg = e.target.closest('.msg')
|
||||
let isChatLine = e.target.id == 'chatline'
|
||||
let isChatEmptySpace = e.target.id == 'messages'
|
||||
let isUI = e.target.closest('.ui')
|
||||
//console.dir({class: e.target.className, id: e.target.id, isChatMsg,isChatLine,isChatEmptySpace,isUI, tagName: e.target.tagName})
|
||||
if( isUI || e.target.tagName.match(/^(BUTTON|TEXTAREA|INPUT|A)/) || e.target.className.match(/(btn)/) ) return
|
||||
if( show ){
|
||||
$chat.visible = true
|
||||
}else{
|
||||
$chat.visible = false
|
||||
$menu.toggle(false)
|
||||
}
|
||||
return true
|
||||
}
|
||||
document.addEventListener('mousedown', showUI(false) )
|
||||
document.addEventListener('mouseup', showUI(true) )
|
||||
document.addEventListener('touchstart', showUI(false) )
|
||||
document.addEventListener('touchend', showUI(true) )
|
||||
},
|
||||
|
||||
loadFile(contentLoaders, multiple){
|
||||
return () => {
|
||||
window.notify("if you're on Meta browser, file-uploads might be disabled")
|
||||
|
|
@ -218,10 +242,11 @@ window.frontend = (opts) => new Proxy({
|
|||
|
||||
share(opts){
|
||||
opts = opts || {notify:true,qr:true,share:true,linkonly:false}
|
||||
if( network.connected && !document.location.hash.match(/meet=/) ){
|
||||
let p = $connections.chatnetwork.find( (p) => p.profile.name == $connections.selectedChatnetwork )
|
||||
console.dir(p)
|
||||
if( p.link ) document.location.hash = `${ network.pos ? `pos=${network.pos}` : ''}&meet=${p.link}`
|
||||
if( network.meetingLink && !document.location.hash.match(/meet=/) ){
|
||||
document.location.hash += `&meet=${network.meetingLink}`
|
||||
}
|
||||
if( !document.location.hash.match(/pos=/) ){
|
||||
document.location.hash += `&pos=${ network.posName || network.pos }`
|
||||
}
|
||||
let url = window.location.href
|
||||
if( opts.linkonly ) return url
|
||||
|
|
|
|||
|
|
@ -60,8 +60,7 @@ window.network = (opts) => new Proxy({
|
|||
for ( var i in String.prototype ) add(i)
|
||||
var a = names[Math.floor(Math.random() * names.length)];
|
||||
var b = names[Math.floor(Math.random() * names.length)];
|
||||
var c = names[Math.floor(Math.random() * names.length)];
|
||||
return String(`${a}-${b}-${c}`).toLowerCase()
|
||||
return String(`${a}-${b}-${String(Math.random()).substr(13)}`).toLowerCase()
|
||||
}
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ window.matrix = (opts) => new Proxy({
|
|||
<tr>
|
||||
<td>user</td>
|
||||
<td>
|
||||
<input type="text" id="username" placeholder="@you:matrix.org"/>
|
||||
<input type="text" id="username" placeholder="@you:matrix.org" value="${opts.plugin.username}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -76,7 +76,8 @@ window.matrix = (opts) => new Proxy({
|
|||
init(){
|
||||
frontend.plugin['matrix'] = this
|
||||
$connections.chatnetwork = $connections.chatnetwork.concat([this])
|
||||
$connections.scene = $connections.chatnetwork.concat([this])
|
||||
$connections.scene = $connections.scene.concat([this])
|
||||
if( window.localStorage.getItem("username") ) this.username = window.localStorage.getItem("username")
|
||||
this.reactToConnectionHrefs()
|
||||
|
||||
document.addEventListener('network.connect', (e) => this.connect(e.detail) )
|
||||
|
|
@ -93,8 +94,8 @@ window.matrix = (opts) => new Proxy({
|
|||
if( opts.selectedChatnetwork == this.profile.name ) this.useChat = true
|
||||
if( opts.selectedScene == this.profile.name ) this.useScene = true
|
||||
if( this.useWebcam || this.useScene || this.useChat ){
|
||||
this.createLink() // ensure link
|
||||
this.link = `matrix://r/${this.channel.replace(/^#/,'')}`
|
||||
this.createLink() // ensure link
|
||||
this.channel = document.querySelector("#matrix input#channel").value
|
||||
this.server = document.querySelector("#matrix input#server").value
|
||||
this.username = document.querySelector("#matrix input#username").value
|
||||
|
|
@ -156,7 +157,10 @@ window.matrix = (opts) => new Proxy({
|
|||
.then( (o) => {
|
||||
console.log(`${this.channel} has id ${o.room_id}`)
|
||||
this.roomId = o.room_id
|
||||
this.setupListeners()
|
||||
// join room if we haven't already
|
||||
this.client.joinRoom(this.roomId)
|
||||
.then( () => this.setupListeners() )
|
||||
.catch( () => this.setupListeners() )
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
|
|
@ -242,7 +246,7 @@ window.matrix = (opts) => new Proxy({
|
|||
formatted_body: message,
|
||||
msgtype:"m.text"
|
||||
}
|
||||
this.client.sendEvent( this.roomId, "m.room.message", content, "", (err,res) => console.error(err) )
|
||||
this.client.sendEvent( this.roomId, "m.room.message", content, "", (err,res) => console.error({err,res}) )
|
||||
})
|
||||
|
||||
},
|
||||
|
|
@ -292,7 +296,7 @@ window.matrix = (opts) => new Proxy({
|
|||
let hash = document.location.hash
|
||||
if( !this.link ){
|
||||
const meeting = network.getMeetingFromUrl(document.location.href)
|
||||
this.link = meeting.match("matrix://") ? meeting : ''
|
||||
this.link = network.meetingLink = meeting.match("matrix://") ? meeting : ''
|
||||
}
|
||||
if( !hash.match('meet=') ) document.location.hash += `${hash.length > 1 ? '&' : '#'}meet=${this.link}`
|
||||
},
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ window.trystero = (opts) => new Proxy({
|
|||
console.log("trystero link: "+this.link)
|
||||
this.room = joinRoom( {appId: 'xrfragment'}, this.link )
|
||||
|
||||
$chat.send({message:`Share the meeting link <a onclick="frontend.share()">by clicking here</a>`,class:['info'],timeout:10000})
|
||||
$chat.send({message:"waiting for other humans..",class:['info'], timeout:5000})
|
||||
$chat.send({message:`Share the meeting link <a onclick="frontend.share()">by clicking here</a>`,class:['info']})
|
||||
$chat.send({message:"waiting for other humans..",class:['info']})
|
||||
|
||||
// setup trystero events
|
||||
const [sendPing, getPing] = this.room.makeAction('ping')
|
||||
|
|
@ -132,6 +132,7 @@ window.trystero = (opts) => new Proxy({
|
|||
this.chat.get = getChat
|
||||
|
||||
document.addEventListener('network.send', (e) => {
|
||||
console.log("trystero")
|
||||
this.chat.send({...e.detail, from: this.nickname, pos: network.pos }) // send to P2P network
|
||||
})
|
||||
// prime chatlog of other people joining
|
||||
|
|
@ -159,7 +160,7 @@ window.trystero = (opts) => new Proxy({
|
|||
video: $connections.$videoInput.value
|
||||
})
|
||||
this.room.addStream(this.selfStream)
|
||||
this.videos[ this.selfId ] = this.getVideo(this.selfId,{stream: this.selfStream})
|
||||
this.getVideo(this.selfId,{create:true,stream: this.selfStream})
|
||||
|
||||
// send stream + chatlog to peers who join later
|
||||
this.room.onPeerJoin( (peerId) => this.room.addStream( this.selfStream, peerId))
|
||||
|
|
@ -198,7 +199,8 @@ window.trystero = (opts) => new Proxy({
|
|||
|
||||
// add video element to the DOM
|
||||
if( opts.stream ) video.srcObject = opts.stream
|
||||
console.log("creating video for peerId")
|
||||
console.log("creating video for peerId "+this.selfId)
|
||||
this.videos[ this.selfId ] = video
|
||||
$chat.$videos.appendChild(video)
|
||||
}
|
||||
},
|
||||
|
|
@ -209,7 +211,7 @@ window.trystero = (opts) => new Proxy({
|
|||
let hash = document.location.hash
|
||||
if( !this.link ){
|
||||
const meeting = network.getMeetingFromUrl(document.location.href)
|
||||
this.link = meeting.match("trystero://") ? meeting : `trystero://r/${network.randomRoom()}:bittorrent`
|
||||
this.link = network.meetingLink = meeting.match("trystero://") ? meeting : `trystero://r/${network.randomRoom()}:bittorrent`
|
||||
}
|
||||
if( !hash.match('meet=') ) document.location.hash += `${hash.length > 1 ? '&' : '#'}meet=${this.link}`
|
||||
},
|
||||
|
|
|
|||
|
|
@ -53,15 +53,6 @@ xrf.getFile = (url) => url.split("/").pop().replace(/#.*/,'')
|
|||
xrf.parseModel = function(model,url){
|
||||
let file = xrf.getFile(url)
|
||||
model.file = file
|
||||
model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.hashbus.pub.mesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.emit('parseModel',{model,url,file})
|
||||
}
|
||||
|
|
@ -93,6 +84,8 @@ xrf.reset = () => {
|
|||
// remove mixers
|
||||
xrf.mixers.map( (m) => m.stop())
|
||||
xrf.mixers = []
|
||||
// set the player to position 0,0,0
|
||||
xrf.camera.position.set(0,0,0)
|
||||
}
|
||||
|
||||
xrf.parseUrl = (url) => {
|
||||
|
|
|
|||
|
|
@ -38,29 +38,42 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
return resolve(xrf.model)
|
||||
}
|
||||
|
||||
// clear xrf objects from scene
|
||||
if( xrf.model && xrf.model.scene ) xrf.model.scene.visible = false
|
||||
xrf.reset()
|
||||
|
||||
// force relative path for files which dont include protocol or relative path
|
||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
||||
url = url.replace(dir,"")
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
const onLoad = (model) => {
|
||||
xrf.reset() // clear xrf objects from scene
|
||||
|
||||
model.file = file
|
||||
// only change url when loading *another* file
|
||||
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
|
||||
xrf.model = model
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.hashbus.pub.mesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
if( hash ) xrf.navigator.updateHash(hash)
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
if( data ) loader.parse(data, "", onLoad )
|
||||
else loader.load(url, onLoad )
|
||||
if( data ){ // file upload
|
||||
loader.parse(data, "", onLoad )
|
||||
}else loader.load(url, onLoad )
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
|||
if( n.userData && n.userData['#'] ){
|
||||
let frag = xrf.URI.parse( n.userData['#'] )
|
||||
if( n.parent && n.parent.parent.isScene && document.location.hash.length < 2 ){
|
||||
xrf.navigator.to( n.userData['#'] ) // evaluate main scene XR fragments and update URL
|
||||
xrf.navigator.to( n.userData['#'] ) // evaluate static XR fragments
|
||||
console.log("to")
|
||||
}else{
|
||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||
console.log("pub")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ xrf.frag.href = function(v, opts){
|
|||
|
||||
let toFrag = xrf.URI.parse( v.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA )
|
||||
// always commit current location in case of teleport (keep a trail of last positions before we navigate)
|
||||
if( isLocal && !hasPos ){
|
||||
xrf.hashbus.pub( v.string, xrf.model ) // publish to hashbus
|
||||
}else{
|
||||
//if( isLocal && !hasPos ){
|
||||
// xrf.hashbus.pub( v.string, xrf.model ) // publish to hashbus
|
||||
//}else{
|
||||
//if( !e.nocommit && !document.location.hash.match(lastPos) ) xrf.navigator.updateHash(`#${lastPos}`)
|
||||
xrf.navigator.to(v.string) // let's surf
|
||||
}
|
||||
//}
|
||||
})
|
||||
.catch( console.error )
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ xrf.addEventListener('env', (opts) => {
|
|||
//scene.texture = env.material.map
|
||||
// renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
||||
// renderer.toneMappingExposure = 2;
|
||||
console.log(` └ applied image '${frag.env.string}' as environment map`)
|
||||
// console.log(` └ applied image '${frag.env.string}' as environment map`)
|
||||
}
|
||||
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue