janusweb 1.5.42 → 1.5.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +23 -0
- package/css/janusweb.css +7 -2
- package/media/assets/webui/apps/buttons/buttons.js +17 -3
- package/media/assets/webui/apps/comms/comms.js +1 -1
- package/media/assets/webui/apps/comms/voip.css +12 -3
- package/media/assets/webui/apps/comms/voip.js +16 -6
- package/media/assets/webui/apps/editor/editor.css +1 -0
- package/media/assets/webui/apps/editor/editor.js +19 -12
- package/media/assets/webui/apps/locomotion/teleporter.js +3 -2
- package/media/assets/webui/apps/xrmenu/images/audio-settings.png +0 -0
- package/media/assets/webui/apps/xrmenu/xrmenu-assets.json +2 -1
- package/media/assets/webui/apps/xrmenu/xrmenu.js +109 -27
- package/media/assets/webui/themes/default.css +42 -0
- package/package.json +2 -2
- package/scripts/client.js +1 -1
- package/scripts/elements/outliner.js +7 -1
- package/scripts/external/JanusClientConnection.js +14 -8
- package/scripts/image.js +1 -1
- package/scripts/janusbase.js +37 -15
- package/scripts/janusghost.js +8 -6
- package/scripts/januslight.js +46 -4
- package/scripts/janusparticle.js +116 -13
- package/scripts/janusplayer.js +59 -12
- package/scripts/janusweb.js +1 -1
- package/scripts/janusxrplayer.js +104 -14
- package/scripts/object.js +63 -30
- package/scripts/parts.js +1 -1
- package/scripts/portal.js +13 -9
- package/scripts/remoteplayer.js +3 -2
- package/scripts/room.js +86 -22
- package/scripts/text.js +7 -2
- package/scripts/websurface.js +3 -3
package/scripts/room.js
CHANGED
|
@@ -27,6 +27,7 @@ elation.require([
|
|
|
27
27
|
'baseurl': { type: 'string', default: false },
|
|
28
28
|
'source': { type: 'string' },
|
|
29
29
|
'skybox': { type: 'boolean', default: true, set: this.toggleSkybox },
|
|
30
|
+
'skybox_intensity': { type: 'float', set: this.setSkybox, default: 1.0 },
|
|
30
31
|
'skybox_equi': { type: 'string', set: this.setSkybox },
|
|
31
32
|
'skybox_left_id': { type: 'string', set: this.setSkybox },
|
|
32
33
|
'skybox_right_id': { type: 'string', set: this.setSkybox },
|
|
@@ -68,7 +69,7 @@ elation.require([
|
|
|
68
69
|
'server': { type: 'string' },
|
|
69
70
|
'port': { type: 'int' },
|
|
70
71
|
'rate': { type: 'int', default: 200 },
|
|
71
|
-
'voip': { type: 'string', default: '
|
|
72
|
+
'voip': { type: 'string', default: 'none' },
|
|
72
73
|
'voipid': { type: 'string' },
|
|
73
74
|
'voiprange': { type: 'float', default: 1 },
|
|
74
75
|
'voipserver': { type: 'string', default: 'voip.janusxr.org' },
|
|
@@ -79,7 +80,7 @@ elation.require([
|
|
|
79
80
|
'requires': { type: 'string' },
|
|
80
81
|
'onload': { type: 'string' },
|
|
81
82
|
'sync': { type: 'boolean', default: false },
|
|
82
|
-
'pointerlock': { type: 'boolean', default: true },
|
|
83
|
+
'pointerlock': { type: 'boolean', default: true, set: this.updatePointerLock },
|
|
83
84
|
});
|
|
84
85
|
this.translators = {
|
|
85
86
|
'^janus-vfs:': elation.janusweb.translators.janusvfs({janus: this.janus}),
|
|
@@ -113,6 +114,7 @@ elation.require([
|
|
|
113
114
|
this.customElements = {};
|
|
114
115
|
this.unknownElements = {};
|
|
115
116
|
this.eventlistenerproxies = {};
|
|
117
|
+
this.pendingScriptMap = {};
|
|
116
118
|
|
|
117
119
|
// FIXME - binding functions to this instance so we can unbind events later. Should be done at a lower level
|
|
118
120
|
this.onRoomEdit = elation.bind(this, this.onRoomEdit);
|
|
@@ -138,6 +140,7 @@ elation.require([
|
|
|
138
140
|
let hashidx = this.url.indexOf('#');
|
|
139
141
|
if (hashidx != -1) {
|
|
140
142
|
this.urlhash = this.url.substr(hashidx+1);
|
|
143
|
+
this.setHash(this.urlhash)
|
|
141
144
|
this.url = this.url.substr(0, hashidx);
|
|
142
145
|
}
|
|
143
146
|
this.roomid = md5(this.url);
|
|
@@ -274,7 +277,7 @@ elation.require([
|
|
|
274
277
|
let obj = this.getObjectById(this.urlhash);
|
|
275
278
|
if (obj) {
|
|
276
279
|
obj.localToWorld(spawnpoint.position.set(0,0,0));
|
|
277
|
-
spawnpoint.orientation.setFromRotationMatrix(obj.objects['3d'].matrixWorld);
|
|
280
|
+
spawnpoint.orientation.setFromRotationMatrix(obj.objects['3d'].matrixWorld.lookAt(spawnpoint.position, obj.localToWorld(V(0,0,1)), obj.localToWorld(V(0,1,0).sub(spawnpoint.position))));
|
|
278
281
|
}
|
|
279
282
|
}
|
|
280
283
|
return spawnpoint;
|
|
@@ -307,9 +310,11 @@ elation.require([
|
|
|
307
310
|
elation.events.add(equi, 'asset_load', ev => {
|
|
308
311
|
this.skyboxtexture = ev.target._texture;
|
|
309
312
|
this.skyboxtexture.mapping = THREE.EquirectangularReflectionMapping;
|
|
313
|
+
this.skyboxtexture.encoding = THREE.sRGBEncoding;
|
|
310
314
|
if (this.janus.currentroom === this) {
|
|
311
315
|
this.skyboxobj.setTexture(this.skyboxtexture);
|
|
312
316
|
}
|
|
317
|
+
elation.events.fire({element: this, type: 'skybox_update'});
|
|
313
318
|
});
|
|
314
319
|
equi.getInstance();
|
|
315
320
|
} else if (hasSkybox) {
|
|
@@ -885,9 +890,9 @@ elation.require([
|
|
|
885
890
|
// If no reciprocal link was found, spawn one so we can find our way back
|
|
886
891
|
let linkrot = new EulerDegrees();
|
|
887
892
|
linkrot.radians.copy(this.spawnpoint.rotation);
|
|
888
|
-
//linkrot.x *= THREE.
|
|
893
|
+
//linkrot.x *= THREE.MathUtils.RAD2DEG;
|
|
889
894
|
linkrot.y = linkrot.y + 180;
|
|
890
|
-
//linkrot.z *= THREE.
|
|
895
|
+
//linkrot.z *= THREE.MathUtils.RAD2DEG;
|
|
891
896
|
let linkpos = this.spawnpoint.localToWorld(V(0,0,player.fatness/2));
|
|
892
897
|
this.createObject('link', {
|
|
893
898
|
pos: linkpos,
|
|
@@ -973,7 +978,6 @@ elation.require([
|
|
|
973
978
|
|
|
974
979
|
if (assets.scripts) {
|
|
975
980
|
this.pendingScripts = 0;
|
|
976
|
-
this.pendingScriptMap = {};
|
|
977
981
|
this.loadScripts(assets.scripts);
|
|
978
982
|
}
|
|
979
983
|
|
|
@@ -1064,7 +1068,7 @@ elation.require([
|
|
|
1064
1068
|
|
|
1065
1069
|
if (this.audionodes) {
|
|
1066
1070
|
this.audionodes.gain.connect(this.audionodes.listener.getInput());
|
|
1067
|
-
console.log('connect room audio to graph', this.audionodes.gain, this.audionodes.listener.getInput(), this);
|
|
1071
|
+
//console.log('connect room audio to graph', this.audionodes.gain, this.audionodes.listener.getInput(), this);
|
|
1068
1072
|
this.fadeAudioIn(2);
|
|
1069
1073
|
}
|
|
1070
1074
|
this.engine.systems.controls.pointerLockEnabled = this.pointerlock;
|
|
@@ -1508,6 +1512,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
1508
1512
|
type: args.type,
|
|
1509
1513
|
format: args.format,
|
|
1510
1514
|
hls: args.hls,
|
|
1515
|
+
proxy: args.proxy,
|
|
1511
1516
|
baseurl: this.baseurl
|
|
1512
1517
|
});
|
|
1513
1518
|
}
|
|
@@ -2071,6 +2076,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2071
2076
|
pickable: ['property', 'pickable'],
|
|
2072
2077
|
|
|
2073
2078
|
skybox: ['property', 'skybox'],
|
|
2079
|
+
skybox_intensity: ['property', 'skybox_intensity'],
|
|
2074
2080
|
skybox_equi: ['property', 'skybox_equi'],
|
|
2075
2081
|
skybox_left_id: ['property', 'skybox_left_id'],
|
|
2076
2082
|
skybox_right_id:['property', 'skybox_right_id'],
|
|
@@ -2166,29 +2172,72 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2166
2172
|
//changestr += this.currentroom.changes[id];
|
|
2167
2173
|
var change = this.changes[id];
|
|
2168
2174
|
var real = this.getObjectFromProxy(change);
|
|
2175
|
+
let propdefs = real._thingdef.properties,
|
|
2176
|
+
proxydefs = change._proxydefs;
|
|
2169
2177
|
if (real) {
|
|
2170
|
-
var xmltype =
|
|
2178
|
+
var xmltype = false;
|
|
2179
|
+
if (room.customElements) {
|
|
2180
|
+
for (let k in room.customElements) {
|
|
2181
|
+
if (room.customElements[k].classname == real.type) {
|
|
2182
|
+
xmltype = k;
|
|
2183
|
+
break;
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
if (!xmltype) {
|
|
2188
|
+
if (real.type in janus.customElements) {
|
|
2189
|
+
xmltype = real.type;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
if (!xmltype) {
|
|
2193
|
+
xmltype = typemap[real.type] || 'Object';
|
|
2194
|
+
}
|
|
2171
2195
|
let xmlnode = xmldoc.createElement(xmltype);
|
|
2172
2196
|
|
|
2173
2197
|
var attrs = Object.keys(change);
|
|
2174
2198
|
for (var i = 0; i < attrs.length; i++) {
|
|
2175
2199
|
var k = attrs[i];
|
|
2176
2200
|
|
|
2201
|
+
let propdef = propdefs[proxydefs[k][1]];
|
|
2202
|
+
|
|
2177
2203
|
if (ignoreattributes.indexOf(k) != -1) continue;
|
|
2178
2204
|
|
|
2205
|
+
let defaultval = (propdef ? propdef.default : null);
|
|
2179
2206
|
var val = change[k];
|
|
2180
|
-
if (val instanceof THREE.Vector2
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2207
|
+
if (val instanceof THREE.Vector2) {
|
|
2208
|
+
if (defaultval instanceof THREE.Vector2) defaultval = defaultval.toArray();
|
|
2209
|
+
//if (!('default' in propdef) || ('default' in propdef && !(val.x == defaultval[0] && val.y == defaultval[1]))) {
|
|
2210
|
+
val = val.toArray().map(function(n) { return (+n).toFixed(4); }).join(' ');
|
|
2211
|
+
//} else {
|
|
2212
|
+
// val = null;
|
|
2213
|
+
//}
|
|
2214
|
+
} else if (val instanceof THREE.Quaternion) {
|
|
2215
|
+
//if (defaultval instanceof THREE.Quaternion) defaultval = defaultval.toArray();
|
|
2216
|
+
//if (!('default' in propdef) || ('default' in propdef && !(val.x == defaultval[0] && val.y == defaultval[1] && val.z == defaultval[2] && val.w == defaultval[3]))) {
|
|
2217
|
+
val = val.toArray().map(function(n) { return (+n).toFixed(4); }).join(' ');
|
|
2218
|
+
//} else {
|
|
2219
|
+
// val = null;
|
|
2220
|
+
//}
|
|
2221
|
+
} else if (val instanceof THREE.Vector3) {
|
|
2222
|
+
if (defaultval instanceof THREE.Vector3) defaultval = defaultval.toArray();
|
|
2223
|
+
//if (!('default' in propdef) || ('default' in propdef && !(val.x == defaultval[0] && val.y == defaultval[1] && val.z == defaultval[2]))) {
|
|
2224
|
+
val = val.toArray().map(function(n) { return (+n).toFixed(4); }).join(' ');
|
|
2225
|
+
//} else {
|
|
2226
|
+
// val = null;
|
|
2227
|
+
//}
|
|
2184
2228
|
} else if (val instanceof THREE.Euler) {
|
|
2185
|
-
|
|
2229
|
+
if (defaultval instanceof THREE.Euler) defaultval = defaultval.toArray();
|
|
2230
|
+
//if (!('default' in propdef) || ('default' in propdef && !(val.x == defaultval[0] && val.y == defaultval[1] && val.z == defaultval[2]))) {
|
|
2231
|
+
val = [val.x.toFixed(4), val.y.toFixed(4), val.z.toFixed(4)].join(' ');
|
|
2232
|
+
//} else {
|
|
2233
|
+
// val = null;
|
|
2234
|
+
//}
|
|
2186
2235
|
} else if (val instanceof THREE.Color) {
|
|
2187
|
-
if (k == 'col' && real.colorIsDefault) {
|
|
2188
|
-
|
|
2189
|
-
} else {
|
|
2236
|
+
//if (k == 'col' && real.colorIsDefault) {
|
|
2237
|
+
// val = null;
|
|
2238
|
+
//} else {
|
|
2190
2239
|
val = val.toArray().map(function(n) { return +n.toFixed(4); }).join(' ');
|
|
2191
|
-
}
|
|
2240
|
+
//}
|
|
2192
2241
|
} else if (elation.utils.isString(val) && val.indexOf('blob:') == 0) {
|
|
2193
2242
|
var xhr = new XMLHttpRequest();
|
|
2194
2243
|
|
|
@@ -2211,6 +2260,15 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2211
2260
|
}
|
|
2212
2261
|
val = 'data:image/png;base64,' + btoa(binary);
|
|
2213
2262
|
*/
|
|
2263
|
+
} else if (elation.utils.isArray(val)) {
|
|
2264
|
+
//if ('default' in propdef && val.length == 0) {
|
|
2265
|
+
// FIXME - this assumes if a default array is provided, it's probably empty. This may not always be true.
|
|
2266
|
+
// val = null;
|
|
2267
|
+
//}
|
|
2268
|
+
} else {
|
|
2269
|
+
//if ('default' in propdef && val == defaultval) {
|
|
2270
|
+
// val = null;
|
|
2271
|
+
//}
|
|
2214
2272
|
}
|
|
2215
2273
|
|
|
2216
2274
|
if (val !== null && val !== undefined && typeof val != 'function') {
|
|
@@ -2403,7 +2461,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2403
2461
|
} else if (val instanceof THREE.Euler) {
|
|
2404
2462
|
if (defaultval instanceof THREE.Euler) defaultval = defaultval.toArray();
|
|
2405
2463
|
if (!('default' in propdef) || ('default' in propdef && !(val.x == defaultval[0] && val.y == defaultval[1] && val.z == defaultval[2]))) {
|
|
2406
|
-
objectsrc += ' ' + k + '="' + val.toArray().slice(0, 3).map(n => Math.round((n * THREE.
|
|
2464
|
+
objectsrc += ' ' + k + '="' + val.toArray().slice(0, 3).map(n => Math.round((n * THREE.MathUtils.RAD2DEG) * 10000) / 10000).join(' ') + '"';
|
|
2407
2465
|
}
|
|
2408
2466
|
} else if (val instanceof THREE.Quaternion) {
|
|
2409
2467
|
if (defaultval instanceof THREE.Quaternion) defaultval = defaultval.toArray();
|
|
@@ -2512,10 +2570,11 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2512
2570
|
_ray = new THREE.Raycaster();
|
|
2513
2571
|
_ray.params.Line.threshold = 3;
|
|
2514
2572
|
_ray.params.Points.threshold = 3;
|
|
2515
|
-
return function(dir, pos, classname, maxdist) {
|
|
2573
|
+
return function(dir, pos, classname, maxdist, colliderroot=null) {
|
|
2516
2574
|
_ray.set(pos, dir);
|
|
2517
2575
|
_ray.far = maxdist || Infinity;
|
|
2518
|
-
|
|
2576
|
+
if (!colliderroot) colliderroot = this.colliders;
|
|
2577
|
+
var intersections = _ray.intersectObject(colliderroot, true);
|
|
2519
2578
|
var hits = [];
|
|
2520
2579
|
if (classname) {
|
|
2521
2580
|
for (var i = 0; i < intersections.length; i++) {
|
|
@@ -2598,17 +2657,19 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
|
|
|
2598
2657
|
});
|
|
2599
2658
|
if (!this.loaded && this.pendingScripts) {
|
|
2600
2659
|
// We're still waiting for the room to finish loading, so wait for the room_load_complete event before checking if we need to load anything else
|
|
2601
|
-
|
|
2660
|
+
let func = (ev) => {
|
|
2602
2661
|
// Room and all of its assets have finished loading. If our required component still isn't available, check the master package list and autoload if possible
|
|
2603
2662
|
if (!finished) {
|
|
2604
2663
|
this.loadComponentList().then(components => {
|
|
2605
2664
|
if (components[k]) {
|
|
2606
2665
|
this.loadNewAsset('script', { src: components[k].url, override: { room: this.getProxyObject() } });
|
|
2607
2666
|
this._target.loadScripts([{src: components[k].url}]);
|
|
2667
|
+
this.removeEventListener('room_load_complete', func);
|
|
2608
2668
|
}
|
|
2609
2669
|
});
|
|
2610
2670
|
}
|
|
2611
|
-
}
|
|
2671
|
+
}
|
|
2672
|
+
this.addEventListener('room_load_complete', func);
|
|
2612
2673
|
} else {
|
|
2613
2674
|
// Room is already loaded and scripts are processed - we still don't know about this component, so load it up
|
|
2614
2675
|
this.loadComponentList().then(components => {
|
|
@@ -2870,6 +2931,9 @@ console.log('unknown material', mat);
|
|
|
2870
2931
|
}
|
|
2871
2932
|
return stats;
|
|
2872
2933
|
}
|
|
2934
|
+
this.updatePointerLock = function() {
|
|
2935
|
+
this.engine.systems.controls.pointerLockEnabled = this.pointerlock;
|
|
2936
|
+
}
|
|
2873
2937
|
}, elation.engine.things.generic);
|
|
2874
2938
|
});
|
|
2875
2939
|
|
package/scripts/text.js
CHANGED
|
@@ -14,7 +14,8 @@ elation.require(['engine.things.label'], function() {
|
|
|
14
14
|
'zalign': { type: 'string', default: 'back', refreshGeometry: true },
|
|
15
15
|
'emissive': { type: 'color', default: 0x000000 },
|
|
16
16
|
'opacity': { type: 'float', default: 1.0 },
|
|
17
|
-
'
|
|
17
|
+
'depth_write': { type: 'bool', default: true },
|
|
18
|
+
'depth_test': { type: 'bool', default: true },
|
|
18
19
|
'thickness': { type: 'float', refreshGeometry: true },
|
|
19
20
|
'segments': { type: 'int', default: 6, refreshGeometry: true },
|
|
20
21
|
'bevel': { type: 'bool', default: false, refreshGeometry: true },
|
|
@@ -82,6 +83,9 @@ elation.require(['engine.things.label'], function() {
|
|
|
82
83
|
this.mesh = mesh;
|
|
83
84
|
}
|
|
84
85
|
this.objects['3d'].add(mesh);
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
//this.setCollider('box', this.getBoundingBox(true));
|
|
88
|
+
}, 0);
|
|
85
89
|
this.refresh();
|
|
86
90
|
}
|
|
87
91
|
this.createTextMaterial = function() {
|
|
@@ -91,7 +95,8 @@ elation.require(['engine.things.label'], function() {
|
|
|
91
95
|
transparent: this.properties.opacity < 1,
|
|
92
96
|
emissive: this.properties.emissive,
|
|
93
97
|
flatShading: false,
|
|
94
|
-
depthTest: this.
|
|
98
|
+
depthTest: this.depth_test,
|
|
99
|
+
depthWrite: this.depth_write,
|
|
95
100
|
reflectivity: .5,
|
|
96
101
|
wireframe: this.wireframe,
|
|
97
102
|
};
|
package/scripts/websurface.js
CHANGED
|
@@ -45,7 +45,7 @@ elation.require(['engine.things.generic'], function() {
|
|
|
45
45
|
elation.events.add(this, 'click', elation.bind(this, this.click));
|
|
46
46
|
}
|
|
47
47
|
this.createObject3D = function() {
|
|
48
|
-
var plane = new THREE.
|
|
48
|
+
var plane = new THREE.PlaneGeometry(1,1);
|
|
49
49
|
|
|
50
50
|
var mat = new THREE.MeshBasicMaterial({
|
|
51
51
|
color: 0x000000,
|
|
@@ -113,7 +113,7 @@ elation.require(['engine.things.generic'], function() {
|
|
|
113
113
|
if (!this.active) {
|
|
114
114
|
var canvas = this.engine.client.view.rendersystem.renderer.domElement;
|
|
115
115
|
canvas.style.pointerEvents = 'none';
|
|
116
|
-
canvas.style.position = 'absolute';
|
|
116
|
+
//canvas.style.position = 'absolute';
|
|
117
117
|
this.engine.systems.controls.releasePointerLock();
|
|
118
118
|
this.active = true;
|
|
119
119
|
this.selectionmaterial.color.copy(this.activecolor);
|
|
@@ -127,7 +127,7 @@ setTimeout(elation.bind(this, function() {
|
|
|
127
127
|
if (this.active) {
|
|
128
128
|
var canvas = this.engine.client.view.rendersystem.renderer.domElement;
|
|
129
129
|
canvas.style.pointerEvents = 'all';
|
|
130
|
-
canvas.style.position = 'static';
|
|
130
|
+
//canvas.style.position = 'static';
|
|
131
131
|
this.engine.systems.controls.requestPointerLock();
|
|
132
132
|
ev.stopPropagation();
|
|
133
133
|
ev.preventDefault();
|