janusweb 1.5.30 → 1.5.34
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 +39 -0
- package/LICENSE +1 -1
- package/media/assets/janus-avatar-animations.glb +0 -0
- package/media/assets/janus-avatar-base.glb +0 -0
- package/media/assets/webui/apps/avatar/avatar.css +6 -2
- package/media/assets/webui/apps/avatar/avatar.js +99 -11
- package/media/assets/webui/apps/buttons/buttons.html +2 -2
- package/media/assets/webui/apps/buttons/buttons.js +3 -3
- package/media/assets/webui/apps/comms/comms.js +7 -4
- package/media/assets/webui/apps/comms/voip.js +133 -57
- package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
- package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
- package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
- package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
- package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
- package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
- package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
- package/media/assets/webui/apps/editor/editor.css +3 -0
- package/media/assets/webui/apps/editor/editor.js +409 -9
- package/media/assets/webui/apps/editor/editor.json +6 -3
- package/media/assets/webui/apps/inventory/inventory.html +7 -4
- package/media/assets/webui/apps/inventory/inventory.js +2 -2
- package/media/assets/webui/apps/locomotion/teleporter.js +10 -9
- package/media/assets/webui/apps/navigation/navigation.js +12 -12
- package/media/assets/webui/apps/settings/settings.html +1 -1
- package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
- package/media/assets/webui/apps/vfs/vfs.css +52 -0
- package/media/assets/webui/apps/vfs/vfs.js +452 -0
- package/media/assets/webui/apps/vfs/vfs.json +10 -0
- package/media/assets/webui/apps/virtualgamepad/virtualgamepad.js +9 -7
- package/media/assets/webui/apps/xrmenu/xrmenu.js +13 -4
- package/media/assets/webui/default.json +2 -1
- package/media/assets/webui/none.json +1 -0
- package/media/assets/webui/themes/default.css +29 -2
- package/media/assets.json +2 -1
- package/media/index.html +1 -1
- package/media/lib/draco/README.md +32 -0
- package/media/lib/draco/draco_decoder.js +52 -0
- package/media/lib/draco/draco_decoder.wasm +0 -0
- package/media/lib/draco/draco_encoder.js +33 -0
- package/media/lib/draco/draco_wasm_wrapper.js +104 -0
- package/media/lib/draco/gltf/draco_decoder.js +48 -0
- package/media/lib/draco/gltf/draco_decoder.wasm +0 -0
- package/media/lib/draco/gltf/draco_encoder.js +33 -0
- package/media/lib/draco/gltf/draco_wasm_wrapper.js +104 -0
- package/media/lib/physx/physx.release.js +21 -0
- package/media/lib/physx/physx.release.wasm +0 -0
- package/media/manifest.json +5 -5
- package/media/service-worker.js +7 -0
- package/package.json +2 -9
- package/scripts/client.js +67 -46
- package/scripts/config.js +2 -0
- package/scripts/elements/linesegments.js +10 -3
- package/scripts/external/JanusFireboxParser.js +1 -0
- package/scripts/image.js +7 -1
- package/scripts/janusbase.js +104 -43
- package/scripts/janusghost.js +314 -16
- package/scripts/januslight.js +11 -2
- package/scripts/janusparagraph.js +8 -6
- package/scripts/janusparticle.js +26 -16
- package/scripts/janusplayer.js +126 -37
- package/scripts/janusweb.js +26 -2
- package/scripts/janusxrplayer.js +5 -3
- package/scripts/multiplayermanager.js +6 -4
- package/scripts/object.js +246 -88
- package/scripts/portal.js +23 -14
- package/scripts/remoteplayer.js +1 -25
- package/scripts/room.js +199 -77
- package/scripts/sound.js +8 -6
- package/scripts/text.js +13 -5
- package/scripts/translators/janusvfs.js +20 -0
- package/scripts/video.js +1 -1
- package/scripts/websurface.js +17 -3
- package/utils/build.sh +3 -0
- package/utils/init.sh +2 -2
- package/scripts/chat.js +0 -80
- package/scripts/ui.js +0 -265
- package/scripts/urlbar.js +0 -93
- package/templates/janusweb.tpl +0 -3
|
@@ -155,13 +155,13 @@ elation.elements.define('janus.ui.editor.panel', class extends elation.elements.
|
|
|
155
155
|
if (typeof room == 'undefined') return;
|
|
156
156
|
if (!this.manipulator) {
|
|
157
157
|
let view = janus.engine.client.view;
|
|
158
|
-
this.manipulator = new THREE.TransformControls(view.actualcamera, view.
|
|
158
|
+
this.manipulator = new THREE.TransformControls(view.actualcamera, view.canvas);
|
|
159
159
|
|
|
160
160
|
elation.events.add(this.manipulator, 'mouseDown', (ev) => {
|
|
161
161
|
this.roomedit.transforming = true;
|
|
162
162
|
this.editObjectShowInfo(this.roomedit.object);
|
|
163
163
|
if (this.manipulator.object && this.manipulator.object.userData.thing) {
|
|
164
|
-
//elation.events.fire({type: 'admin_edit_start', element: this, data: this.manipulator.object.userData.thing});
|
|
164
|
+
//elation.events.fire({type: 'admin_edit_start', element: this, data: this.manipulator.object.userData.thing});
|
|
165
165
|
//player.disable();
|
|
166
166
|
}
|
|
167
167
|
});
|
|
@@ -271,7 +271,16 @@ console.log('set translation snap', ev.data, ev);
|
|
|
271
271
|
janus.engine.systems.render.setdirty();
|
|
272
272
|
}
|
|
273
273
|
handleViewSourceClick(ev) {
|
|
274
|
-
|
|
274
|
+
if (!this.sourcewindow) {
|
|
275
|
+
let win = elation.elements.create('ui-window', { append: document.body, center: true });
|
|
276
|
+
let editor = elation.elements.create('janus-ui-editor-source', { room: room });
|
|
277
|
+
|
|
278
|
+
win.setcontent(editor);
|
|
279
|
+
setTimeout(() => { win.center = false; }, 1500);
|
|
280
|
+
this.sourcewindow = win;
|
|
281
|
+
} else {
|
|
282
|
+
this.sourcewindow.show();
|
|
283
|
+
}
|
|
275
284
|
}
|
|
276
285
|
handleExportClick(ev) {
|
|
277
286
|
let exporter = new THREE.GLTFExporter();
|
|
@@ -281,7 +290,7 @@ console.log('set translation snap', ev.data, ev);
|
|
|
281
290
|
var url = window.URL.createObjectURL(filedata);
|
|
282
291
|
|
|
283
292
|
let d = new Date(),
|
|
284
|
-
ts = d.getFullYear() + (d.getMonth() + 1).toString().padStart(2, '0') + d.getDate().toString().padStart(2, '0') + d.getHours().toString().padStart(2, '0') + d.getMinutes().toString().padStart(2, '0') + d.getSeconds().toString().padStart(2, '0')
|
|
293
|
+
ts = d.getFullYear() + (d.getMonth() + 1).toString().padStart(2, '0') + d.getDate().toString().padStart(2, '0') + d.getHours().toString().padStart(2, '0') + d.getMinutes().toString().padStart(2, '0') + d.getSeconds().toString().padStart(2, '0');
|
|
285
294
|
|
|
286
295
|
var a = document.createElement('A');
|
|
287
296
|
a.style.display = 'none';
|
|
@@ -433,7 +442,7 @@ console.log('set translation snap', ev.data, ev);
|
|
|
433
442
|
editObjectCloneWireframe(obj, parent, material, constrain) {
|
|
434
443
|
let newobj = null;
|
|
435
444
|
if (obj instanceof THREE.Mesh) {
|
|
436
|
-
newobj = new THREE.Mesh(obj.geometry, material)
|
|
445
|
+
newobj = new THREE.Mesh(obj.geometry, material);
|
|
437
446
|
newobj.matrixAutoUpdate = false;
|
|
438
447
|
newobj.matrix.copy(obj.matrix);
|
|
439
448
|
//newobj.matrixWorld.copy(obj.matrix);
|
|
@@ -694,7 +703,7 @@ obj.opacity = obj.opacity;
|
|
|
694
703
|
if ('min' in attrdef && 'max' in attrdef) {
|
|
695
704
|
min = attrdef.min;
|
|
696
705
|
max = attrdef.max;
|
|
697
|
-
amount *= (max - min) / divisor;
|
|
706
|
+
amount *= (max - min) / divisor;
|
|
698
707
|
} else {
|
|
699
708
|
amount /= divisor;
|
|
700
709
|
}
|
|
@@ -1104,11 +1113,14 @@ console.log('change color', obj.col, vec);
|
|
|
1104
1113
|
}
|
|
1105
1114
|
}
|
|
1106
1115
|
this.history.push({type: 'addobjects', objects: objects});
|
|
1116
|
+
/*
|
|
1107
1117
|
if (janus.engine.systems.admin.hidden) {
|
|
1108
1118
|
janus.engine.systems.controls.requestPointerLock();
|
|
1109
1119
|
}
|
|
1120
|
+
*/
|
|
1110
1121
|
}
|
|
1111
1122
|
handleThingAdd(ev) {
|
|
1123
|
+
console.log('[editor] scene added a thing', ev);
|
|
1112
1124
|
setTimeout(() => {
|
|
1113
1125
|
this.scenetree.refreshList();
|
|
1114
1126
|
}, 0);
|
|
@@ -1134,7 +1146,7 @@ console.log('change color', obj.col, vec);
|
|
|
1134
1146
|
sync: true,
|
|
1135
1147
|
pos: new elation.physics.vector3().copy(player.vectors.cursor_pos),
|
|
1136
1148
|
persist: true
|
|
1137
|
-
}
|
|
1149
|
+
};
|
|
1138
1150
|
if (trimmedurl.length > 0) {
|
|
1139
1151
|
var schemeidx = trimmedurl.indexOf(':');
|
|
1140
1152
|
if (schemeidx != -1) {
|
|
@@ -1217,14 +1229,26 @@ console.log('change color', obj.col, vec);
|
|
|
1217
1229
|
// handle them (eg, video). However, CORS is a nightmare, and most servers don't whitelist Range headers.
|
|
1218
1230
|
|
|
1219
1231
|
// If mime type detection fails, we could also check for known signatures in the first 1k of data, but we don't do that here yet
|
|
1232
|
+
if (false) {
|
|
1220
1233
|
let proxiedurl = url;
|
|
1221
|
-
if (elation.engine.assets.corsproxy && !url.match(/^https?:\/\/localhost/) && !url.match(/^data:/)) {
|
|
1234
|
+
if (elation.engine.assets.corsproxy && !url.match(/^https?:\/\/localhost/) && !url.match(/^data:/) && !url.match(/^janus-vfs:/)) {
|
|
1222
1235
|
proxiedurl = elation.engine.assets.corsproxy + url;
|
|
1223
1236
|
}
|
|
1224
1237
|
fetch(proxiedurl, { headers: { /*'Range': 'bytes=0-1023'}*/ }}).then(res => resolve(res.headers.get('content-type')))
|
|
1225
1238
|
.catch((e) => {
|
|
1226
1239
|
reject();
|
|
1227
1240
|
});
|
|
1241
|
+
} else {
|
|
1242
|
+
elation.engine.assetdownloader.fetchURL(url).then(ev => {
|
|
1243
|
+
let res = ev.target;
|
|
1244
|
+
if (res.headers) {
|
|
1245
|
+
resolve(res.headers.get('content-type'));
|
|
1246
|
+
} else {
|
|
1247
|
+
// FIXME - no headers, unknown type
|
|
1248
|
+
resolve();
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1228
1252
|
});
|
|
1229
1253
|
}
|
|
1230
1254
|
loadObjectFromJML(jml) {
|
|
@@ -1239,7 +1263,8 @@ console.log('change color', obj.col, vec);
|
|
|
1239
1263
|
args = {
|
|
1240
1264
|
id: name,
|
|
1241
1265
|
pos: player.vectors.cursor_pos.clone(),
|
|
1242
|
-
sync: true
|
|
1266
|
+
sync: true,
|
|
1267
|
+
persist: true,
|
|
1243
1268
|
},
|
|
1244
1269
|
assetargs = {
|
|
1245
1270
|
id: name,
|
|
@@ -1508,6 +1533,381 @@ elation.elements.define('janus.ui.editor.scenetree', class extends elation.eleme
|
|
|
1508
1533
|
elation.events.fire({type: 'select', element: this, data: ev.data.value.getProxyObject()});
|
|
1509
1534
|
}
|
|
1510
1535
|
});
|
|
1536
|
+
elation.elements.define('janus.ui.editor.source', class extends elation.elements.base {
|
|
1537
|
+
async create() {
|
|
1538
|
+
await janus.ui.apps.default.apps.editor.loadScriptsAndCSS([
|
|
1539
|
+
'./codemirror/addon/hint/show-hint.js',
|
|
1540
|
+
'./codemirror/addon/hint/xml-hint.js',
|
|
1541
|
+
'./codemirror/addon/hint/javascript-hint.js',
|
|
1542
|
+
'./codemirror/keymap/vim.js',
|
|
1543
|
+
], [
|
|
1544
|
+
'./codemirror/addon/hint/show-hint.css',
|
|
1545
|
+
]);
|
|
1546
|
+
await room.loadComponentList();
|
|
1547
|
+
this.jmlhints = this.buildJMLMap();
|
|
1548
|
+
|
|
1549
|
+
this.tabs = elation.elements.create('ui-tabs', { append: this });
|
|
1550
|
+
//let roomtab = elation.elements.create('ui-tab', { append: this.tabs, label: 'Room Markup' });
|
|
1551
|
+
let roomedit = elation.elements.create('janus-ui-editor-source-file', { append: this.tabs, label: 'Room Markup', source: room.getRoomSource(), hints: this.jmlhints });
|
|
1552
|
+
|
|
1553
|
+
if (room.roomassets.script) {
|
|
1554
|
+
for (let k in room.roomassets.script) {
|
|
1555
|
+
let scriptasset = room.roomassets.script[k];
|
|
1556
|
+
//let scripttab = elation.elements.create('ui-tab', { append: this.tabs, label: k });
|
|
1557
|
+
let scriptedit = elation.elements.create('janus-ui-editor-source-file', { append: this.tabs, label: k, source: scriptasset.code, mode: 'javascript' });
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
buildJMLMap() {
|
|
1562
|
+
let tagMap = {};
|
|
1563
|
+
for (let tag in janus.customElements) tagMap[tag] = janus.customElements[tag];
|
|
1564
|
+
for (let tag in room.customElements) tagMap[tag] = room.customElements[tag];
|
|
1565
|
+
let allTags = Object.keys(tagMap).sort();
|
|
1566
|
+
|
|
1567
|
+
let hints = {
|
|
1568
|
+
"!top": ["janus-viewer"],
|
|
1569
|
+
"fireboxroom": {
|
|
1570
|
+
children: ['assets', 'room'],
|
|
1571
|
+
},
|
|
1572
|
+
"janus-viewer": {
|
|
1573
|
+
children: ['assets', 'room'],
|
|
1574
|
+
},
|
|
1575
|
+
'assets': {
|
|
1576
|
+
children: ['assetimage', 'assetobject', 'assetfont', 'assetwebsurface', 'assetscript', 'assetsound', 'assetvideo', 'assetshader', 'assetghost'],
|
|
1577
|
+
},
|
|
1578
|
+
'room': {
|
|
1579
|
+
attrs: {},
|
|
1580
|
+
children: allTags,
|
|
1581
|
+
},
|
|
1582
|
+
'assetimage': {
|
|
1583
|
+
attrs: this.getAssetAttributes('image'),
|
|
1584
|
+
},
|
|
1585
|
+
'assetobject': {
|
|
1586
|
+
attrs: this.getAssetAttributes('model'),
|
|
1587
|
+
},
|
|
1588
|
+
'assetfont': {
|
|
1589
|
+
attrs: this.getAssetAttributes('font'),
|
|
1590
|
+
},
|
|
1591
|
+
'assetwebsurface': {
|
|
1592
|
+
attrs: {
|
|
1593
|
+
id: null,
|
|
1594
|
+
src: null,
|
|
1595
|
+
},
|
|
1596
|
+
},
|
|
1597
|
+
'assetscript': {
|
|
1598
|
+
attrs: this.getAssetAttributes('script'),
|
|
1599
|
+
},
|
|
1600
|
+
'assetsound': {
|
|
1601
|
+
attrs: this.getAssetAttributes('sound'),
|
|
1602
|
+
},
|
|
1603
|
+
'assetvideo': {
|
|
1604
|
+
attrs: this.getAssetAttributes('video'),
|
|
1605
|
+
},
|
|
1606
|
+
'assetshader': {
|
|
1607
|
+
attrs: this.getAssetAttributes('shader'),
|
|
1608
|
+
},
|
|
1609
|
+
'assetghost': {
|
|
1610
|
+
attrs: {
|
|
1611
|
+
id: null,
|
|
1612
|
+
src: null,
|
|
1613
|
+
},
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
hints.Room = hints.room;
|
|
1617
|
+
hints.FireBoxRoom = hints.fireboxroom;
|
|
1618
|
+
hints.Assets = hints.assets;
|
|
1619
|
+
hints.AssetImage = hints.assetimage;
|
|
1620
|
+
hints.AssetObject = hints.assetobject;
|
|
1621
|
+
hints.AssetFont = hints.assetfont;
|
|
1622
|
+
hints.AssetWebsurface = hints.assetwebsurface;
|
|
1623
|
+
hints.AssetScript = hints.assetscript;
|
|
1624
|
+
hints.AssetSound = hints.assetsound;
|
|
1625
|
+
hints.AssetVideo = hints.assetvideo;
|
|
1626
|
+
hints.AssetShader = hints.assetshader;
|
|
1627
|
+
hints.AssetGhost = hints.assetghost;
|
|
1628
|
+
|
|
1629
|
+
let roomattrs = this.getAttributes({classname: 'janusroom'}, room);
|
|
1630
|
+
let roomattrkeys = Object.keys(roomattrs).sort();
|
|
1631
|
+
roomattrkeys.forEach(attrname => {
|
|
1632
|
+
if (attrname != 'requires') { // We'll handle <room require="..."> as a special case, partly because of the name mismatch and partly so we can autosuggest components from the repository
|
|
1633
|
+
let attr = roomattrs[attrname];
|
|
1634
|
+
hints['room'].attrs[attrname] = (attr.type == 'boolean' || attr.types == 'bool' ? ['true', 'false'] : null);
|
|
1635
|
+
} else {
|
|
1636
|
+
hints['room'].attrs.require = Object.keys(room.componentrepository).sort();;
|
|
1637
|
+
}
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
hints['room'].attrDelims = { require: ' ' };
|
|
1641
|
+
|
|
1642
|
+
for (let i = 0; i < allTags.length; i++) {
|
|
1643
|
+
let tag = allTags[i],
|
|
1644
|
+
tagdef = tagMap[tag];
|
|
1645
|
+
let attrs = this.getAttributes(tagdef);
|
|
1646
|
+
|
|
1647
|
+
hints[tag] = {
|
|
1648
|
+
attrs: {},
|
|
1649
|
+
children: allTags,
|
|
1650
|
+
};
|
|
1651
|
+
hints[elation.utils.camelize('.' + tag)] = hints[tag]; // capitalize first letter of tag, mapped to the all-lowercase tag definition
|
|
1652
|
+
|
|
1653
|
+
let attrkeys = Object.keys(attrs).sort();
|
|
1654
|
+
attrkeys.forEach(attrname => {
|
|
1655
|
+
let attr = attrs[attrname];
|
|
1656
|
+
hints[tag].attrs[attrname] = (attr.type == 'boolean' || attr.types == 'bool' ? ['true', 'false'] : null);
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// Autocomplete asset ids of various types
|
|
1661
|
+
hints.object.attrs.id =
|
|
1662
|
+
hints.object.attrs.collision_id =
|
|
1663
|
+
hints.particle.attrs.emitter_id =
|
|
1664
|
+
cm => this.getAssetSuggestions('model');
|
|
1665
|
+
|
|
1666
|
+
hints.object.attrs.image_id =
|
|
1667
|
+
hints.object.attrs.normalmap_id =
|
|
1668
|
+
hints.object.attrs.roughness_id =
|
|
1669
|
+
hints.object.attrs.metalness_id =
|
|
1670
|
+
hints.object.attrs.displacementmap_id =
|
|
1671
|
+
hints.object.attrs.emissive_id =
|
|
1672
|
+
hints.object.attrs.alphamap_id =
|
|
1673
|
+
hints.object.attrs.envmap_id =
|
|
1674
|
+
hints.object.attrs.lmap_id =
|
|
1675
|
+
hints.object.attrs.lmap_id =
|
|
1676
|
+
hints.image.attrs.id =
|
|
1677
|
+
hints.image3d.attrs.id =
|
|
1678
|
+
hints.particle.attrs.image_id =
|
|
1679
|
+
hints.link.attrs.thumb_id =
|
|
1680
|
+
hints.room.attrs.skybox_up_id =
|
|
1681
|
+
hints.room.attrs.skybox_down_id =
|
|
1682
|
+
hints.room.attrs.skybox_left_id =
|
|
1683
|
+
hints.room.attrs.skybox_right_id =
|
|
1684
|
+
hints.room.attrs.skybox_front_id =
|
|
1685
|
+
hints.room.attrs.skybox_back_id =
|
|
1686
|
+
hints.room.attrs.skybox_equi =
|
|
1687
|
+
cm => this.getAssetSuggestions('image');
|
|
1688
|
+
|
|
1689
|
+
hints.object.attrs.video_id =
|
|
1690
|
+
hints.video.attrs.video_id =
|
|
1691
|
+
cm => this.getAssetSuggestions('video');
|
|
1692
|
+
|
|
1693
|
+
hints.object.attrs.shader_id =
|
|
1694
|
+
hints.link.attrs.shader_id =
|
|
1695
|
+
cm => this.getAssetSuggestions('shader');
|
|
1696
|
+
|
|
1697
|
+
hints.text.attrs.font = cm => this.getAssetSuggestions('font');
|
|
1698
|
+
hints.sound.attrs.id = cm => this.getAssetSuggestions('sound');
|
|
1699
|
+
|
|
1700
|
+
hints.object.attrs.cull_face =
|
|
1701
|
+
hints.paragraph.attrs.cull_face =
|
|
1702
|
+
['back', 'front', 'none'];
|
|
1703
|
+
|
|
1704
|
+
hints.object.blend_src =
|
|
1705
|
+
hints.object.blend_dest =
|
|
1706
|
+
['zero', 'one', 'src_color', 'dst_color', 'src_alpha', 'dst_alpha', 'one_minus_src_color', 'one_minus_src_alpha', 'one_minus_dst_color', 'one_minus_dst_alpha'];
|
|
1707
|
+
|
|
1708
|
+
hints.room.attrs.fog_mode = ['linear', 'exp', 'exp2'];
|
|
1709
|
+
hints.room.attrs.tonemapping_type = Object.keys(room.toneMappingTypes);
|
|
1710
|
+
|
|
1711
|
+
return hints;
|
|
1712
|
+
}
|
|
1713
|
+
getAssetSuggestions(assettype) {
|
|
1714
|
+
let hints = [];
|
|
1715
|
+
if (janus.assetpack.assetmap[assettype]) Array.prototype.push.apply(hints, Object.keys(janus.assetpack.assetmap[assettype]));
|
|
1716
|
+
if (room.assetpack && room.assetpack.assetmap[assettype]) Array.prototype.push.apply(hints, Object.keys(room.assetpack.assetmap[assettype]));
|
|
1717
|
+
|
|
1718
|
+
return hints.sort();
|
|
1719
|
+
}
|
|
1720
|
+
getAttributes(objdef, bindobj) {
|
|
1721
|
+
console.log('parse the object', objdef);
|
|
1722
|
+
let elationThing = elation.engine.things[objdef.classname];
|
|
1723
|
+
let allProperties = this.parseThingProperties(elationThing, null, bindobj);
|
|
1724
|
+
|
|
1725
|
+
if (!(objdef.class instanceof Function)) {
|
|
1726
|
+
for (let attrname in objdef.class) {
|
|
1727
|
+
let attr = objdef.class[attrname];
|
|
1728
|
+
let attrtype = (attr === true || attr === false ? 'boolean' : 'whatever');
|
|
1729
|
+
allProperties.properties[attrname] = { type: attrtype };
|
|
1730
|
+
allProperties.proxies[attrname] = ['property', attrname];
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
let attrs = {};
|
|
1735
|
+
if (allProperties) {
|
|
1736
|
+
for (let k in allProperties.proxies) {
|
|
1737
|
+
let p = allProperties.proxies[k];
|
|
1738
|
+
if (p[0] == 'property' && allProperties.properties[p[1]]) {
|
|
1739
|
+
let attr = allProperties.properties[p[1]];
|
|
1740
|
+
if (attr.type != 'object') { // Skip object types, since they're generally only used internally
|
|
1741
|
+
attrs[k] = attr;
|
|
1742
|
+
}
|
|
1743
|
+
} else if (p[0] == 'callback') {
|
|
1744
|
+
attrs[k] = { type: 'callback' };
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
return attrs;
|
|
1749
|
+
}
|
|
1750
|
+
getAssetAttributes(assetname) {
|
|
1751
|
+
let attrs = {},
|
|
1752
|
+
props = this.parseAssetProperties(assetname);
|
|
1753
|
+
let propkeys = Object.keys(props).sort();
|
|
1754
|
+
for (let i = 0; i < propkeys.length; i++) {
|
|
1755
|
+
attrs[propkeys[i]] = (props[propkeys[i]].type == 'boolean' ? ['true', 'false'] : null);
|
|
1756
|
+
}
|
|
1757
|
+
return attrs;
|
|
1758
|
+
}
|
|
1759
|
+
parseAssetProperties(assetname) {
|
|
1760
|
+
let props = {};
|
|
1761
|
+
if (elation.engine.assets[assetname]) {
|
|
1762
|
+
let prot = elation.engine.assets[assetname].prototype;
|
|
1763
|
+
let exclude = ['assettype', 'assetpack', 'instances', 'baseurl', 'preview', 'loaded', 'size', 'proxy', 'sourceurl', 'author', 'license', 'description', 'frames', 'canvas', 'rawimage', 'texture', 'video'];
|
|
1764
|
+
for (let k in prot) {
|
|
1765
|
+
if (typeof prot[k] != 'function' && exclude.indexOf(k) == -1) {
|
|
1766
|
+
let attrtype = (prot[k] === true || prot[k] === false ? 'boolean' : 'whatever');
|
|
1767
|
+
let propname = (k == 'name' ? 'id' : k);
|
|
1768
|
+
props[propname] = { type: attrtype };
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
return props;
|
|
1773
|
+
}
|
|
1774
|
+
parseThingProperties(thing, props, bindobj) {
|
|
1775
|
+
if (!props) props = {
|
|
1776
|
+
properties: {},
|
|
1777
|
+
proxies: {}
|
|
1778
|
+
};
|
|
1779
|
+
|
|
1780
|
+
if (thing.extendclassdef) {
|
|
1781
|
+
let parentThing = thing.extendclassdef;
|
|
1782
|
+
this.parseThingProperties(parentThing, props);
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
let mProps = thing.classdef.toString().match(/defineProperties\(({.*?})\)/ms);
|
|
1786
|
+
let mProxies = thing.classdef.toString().match(/(new elation\.proxy\(this, |_proxydefs = )({.*?})[;|\)]/ms);
|
|
1787
|
+
(elation.bind(bindobj || this, function() {
|
|
1788
|
+
if (mProps) {
|
|
1789
|
+
let propmap;
|
|
1790
|
+
eval('propmap = ' + mProps[1]);
|
|
1791
|
+
for (let k in propmap) props.properties[k] = propmap[k];
|
|
1792
|
+
}
|
|
1793
|
+
if (mProxies) {
|
|
1794
|
+
let proxymap;
|
|
1795
|
+
eval('proxymap = ' + mProxies[2]);
|
|
1796
|
+
for (let k in proxymap) props.proxies[k] = proxymap[k];
|
|
1797
|
+
}
|
|
1798
|
+
}))();
|
|
1799
|
+
return props;
|
|
1800
|
+
}
|
|
1801
|
+
});
|
|
1802
|
+
elation.elements.define('janus.ui.editor.source.file', class extends elation.elements.ui.tab {
|
|
1803
|
+
init() {
|
|
1804
|
+
super.init();
|
|
1805
|
+
this.defineAttributes({
|
|
1806
|
+
source: { type: 'string' },
|
|
1807
|
+
filename: { type: 'string', default: 'New File' },
|
|
1808
|
+
mode: { type: 'string', default: 'xml' },
|
|
1809
|
+
hints: { type: 'object' },
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
create() {
|
|
1813
|
+
this.filename = this.label;
|
|
1814
|
+
|
|
1815
|
+
this.initCodemirror();
|
|
1816
|
+
elation.events.add(this.parentNode, 'tabselect', ev => { this.codemirror.refresh(); setTimeout(() => { this.codemirror.focus(); }, 0); });
|
|
1817
|
+
}
|
|
1818
|
+
async initCodemirror() {
|
|
1819
|
+
if (!CodeMirror.modes[this.mode]) {
|
|
1820
|
+
await janus.ui.apps.default.apps.editor.loadScriptsAndCSS([`./codemirror/mode/${this.mode}/${this.mode}.js`]);
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
this.codemirror = CodeMirror(this, {
|
|
1824
|
+
value: this.source,
|
|
1825
|
+
mode: this.mode,
|
|
1826
|
+
lineNumbers: true,
|
|
1827
|
+
extraKeys: {
|
|
1828
|
+
'Ctrl-S': () => this.handleSave(),
|
|
1829
|
+
'Ctrl-Space':(cm) => { CodeMirror.showHint(cm, CodeMirror.hint[this.mode]); },
|
|
1830
|
+
'Ctrl-Alt-V':(cm) => {
|
|
1831
|
+
if (cm.state.keyMaps.indexOf(CodeMirror.keyMap.vim) != -1) {
|
|
1832
|
+
// FIXME - removing the keymap doesn't actually work, the bindings stay active
|
|
1833
|
+
cm.removeKeyMap(CodeMirror.keyMap.vim);
|
|
1834
|
+
} else {
|
|
1835
|
+
cm.addKeyMap(CodeMirror.keyMap.vim);
|
|
1836
|
+
}
|
|
1837
|
+
cm.refresh();
|
|
1838
|
+
},
|
|
1839
|
+
},
|
|
1840
|
+
hintOptions: {
|
|
1841
|
+
autohint: true,
|
|
1842
|
+
schemaInfo: this.hints,
|
|
1843
|
+
matchInMiddle: true,
|
|
1844
|
+
},
|
|
1845
|
+
});
|
|
1846
|
+
console.log('editor hints', this.hints);
|
|
1847
|
+
this.codemirror.on('change', (ev) => this.handleEditContentChange(ev));
|
|
1848
|
+
this.codemirror.on('change', (ev) => this.handleEditContentChange(ev));
|
|
1849
|
+
|
|
1850
|
+
let skipKeyCodes = [
|
|
1851
|
+
8, // backspace
|
|
1852
|
+
9, // tab
|
|
1853
|
+
13, // enter
|
|
1854
|
+
16, // shift
|
|
1855
|
+
17, // ctrl
|
|
1856
|
+
18, // alt
|
|
1857
|
+
27, // esc
|
|
1858
|
+
//32, // space
|
|
1859
|
+
33, // pgup
|
|
1860
|
+
34, // pgdn
|
|
1861
|
+
35, // home
|
|
1862
|
+
36, // end
|
|
1863
|
+
37, // left
|
|
1864
|
+
38, // up
|
|
1865
|
+
39, // right
|
|
1866
|
+
40, // down
|
|
1867
|
+
46, // delete
|
|
1868
|
+
|
|
1869
|
+
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // 0-9
|
|
1870
|
+
186, // ;
|
|
1871
|
+
189, // -
|
|
1872
|
+
219, // {
|
|
1873
|
+
221, // }
|
|
1874
|
+
];
|
|
1875
|
+
if (this.mode == 'javascript') {
|
|
1876
|
+
skipKeyCodes.push(32); // space
|
|
1877
|
+
skipKeyCodes.push(187); // =
|
|
1878
|
+
} else if (this.mode == 'xml') {
|
|
1879
|
+
skipKeyCodes.push(190); // . and >
|
|
1880
|
+
}
|
|
1881
|
+
this.codemirror.on("keyup", function (cm, event) {
|
|
1882
|
+
if ((!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/
|
|
1883
|
+
!event.ctrlKey && !event.altKey &&
|
|
1884
|
+
skipKeyCodes.indexOf(event.keyCode) == -1)) { /*Enter - do not open autocomplete list just after item has been selected in it*/
|
|
1885
|
+
CodeMirror.commands.autocomplete(cm, null, {completeSingle: false});
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
handleSave() {
|
|
1890
|
+
this.source = this.codemirror.getValue();
|
|
1891
|
+
this.label = this.filename;
|
|
1892
|
+
}
|
|
1893
|
+
handleEditContentChange(ev) {
|
|
1894
|
+
//console.log('it changed', ev);
|
|
1895
|
+
let newsource = this.codemirror.getValue();
|
|
1896
|
+
this.dirty = (newsource != this.source);
|
|
1897
|
+
if (this.dirty) {
|
|
1898
|
+
this.label = '*' + this.filename;
|
|
1899
|
+
} else {
|
|
1900
|
+
this.label = this.filename;
|
|
1901
|
+
}
|
|
1902
|
+
if (this.updatetimer) {
|
|
1903
|
+
clearTimeout(this.updatetimer);
|
|
1904
|
+
}
|
|
1905
|
+
this.updatetimer = setTimeout(() => {
|
|
1906
|
+
room.updateSource(newsource);
|
|
1907
|
+
this.updatetimer = false;
|
|
1908
|
+
}, 500);
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1511
1911
|
|
|
1512
1912
|
class ColorTransform extends THREE.Object3D {
|
|
1513
1913
|
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
"janus.ui.editor.panel": "./editor-panel.html",
|
|
4
4
|
"janus.ui.editor.object.info": "./editor-object-info.html"
|
|
5
5
|
},
|
|
6
|
-
"scripts": ["./editor.js", "./editor-properties.js"],
|
|
7
|
-
"css": ["./editor.css"],
|
|
6
|
+
"scripts": ["./editor.js", "./editor-properties.js", "./codemirror/lib/codemirror.js"],
|
|
7
|
+
"css": ["./editor.css", "./codemirror/lib/codemirror.css", "./codemirror/lib/jmldark.css"],
|
|
8
8
|
"components": [
|
|
9
|
-
"janus-ui-editor-panel"
|
|
9
|
+
"janus-ui-editor-panel",
|
|
10
|
+
"janus-ui-editor-objectinfo",
|
|
11
|
+
"janus-ui-editor-scenetree",
|
|
12
|
+
"janus-ui-editor-source"
|
|
10
13
|
]
|
|
11
14
|
}
|
|
12
15
|
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
<ui-tab label="Room Assets">
|
|
38
38
|
<janus-ui-inventory-roomassets></janus-ui-inventory-roomassets>
|
|
39
39
|
</ui-tab>
|
|
40
|
+
<!-- Disabled Google Poly - maybe one day ICOSA Gallery or someone else will offer the old Google Blocks API again
|
|
40
41
|
<ui-tab label="Google Poly">
|
|
41
42
|
<ui-flexpanel id="poly" vertical>
|
|
42
43
|
<ui-input noflex placeholder="Search for Google Poly models" onaccept="let models = document.getElementById('models'); models.apiargs.keywords = this.value; delete models.apiargs.pageToken; document.getElementById('itemlist').clear(); models.load(); pagination.disabled = false;"></ui-input>
|
|
@@ -44,16 +45,18 @@
|
|
|
44
45
|
<ui-button noflex id="pagination" onclick="let models = document.getElementById('models'); if (models.rawdata.nextPageToken) { models.apiargs.pageToken = models.rawdata.nextPageToken; models.append(); } else { this.disabled = true; }">Load More</ui-button>
|
|
45
46
|
</ui-flexpanel>
|
|
46
47
|
</ui-tab>
|
|
47
|
-
|
|
48
|
+
-->
|
|
48
49
|
<ui-tab label="Vesta">
|
|
49
50
|
<h3>Vesta integration coming soon!</h3>
|
|
50
51
|
<p>When it's ready, you'll be able to access assets you've stored on your Vesta account, and bring them with you anywhere you go.</p>
|
|
51
52
|
<p><a href="https://vesta.janusvr.com/">Sign up for a vesta account today</a></p>
|
|
52
53
|
</ui-tab>
|
|
53
54
|
<ui-tab label="Import">
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
<div>
|
|
56
|
+
<h3>Did you know!?</h3>
|
|
57
|
+
<p>You can drag 3d models, images, videos, and sounds into Janus rooms from other websites, or even your local hard drive!</p>
|
|
58
|
+
<p>Just select the files, drag them over, and drop them into the world. Then use our in-world editing tools to place it where you want it to be.</p>
|
|
59
|
+
</div>
|
|
57
60
|
</ui-tab>
|
|
58
61
|
</ui-tabs>
|
|
59
62
|
|
|
@@ -6,7 +6,7 @@ elation.elements.define('janus.ui.inventory', class extends elation.elements.bas
|
|
|
6
6
|
console.log('INVENTORY ELEMENTS', elements);
|
|
7
7
|
if (elements.primitives) {
|
|
8
8
|
elation.events.add(elements.primitives, 'select', (ev) => this.handlePrimitiveSelect(ev));
|
|
9
|
-
elation.events.add(elements.polyobjects, 'select', (ev) => this.handleAssetSelect(ev));
|
|
9
|
+
//elation.events.add(elements.polyobjects, 'select', (ev) => this.handleAssetSelect(ev));
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
addSource(name, collection) {
|
|
@@ -68,7 +68,7 @@ elation.elements.define('janus.ui.inventory.roomassets.list', class extends elat
|
|
|
68
68
|
this.list.setItems(this.getAssetList());
|
|
69
69
|
}
|
|
70
70
|
getAssetList() {
|
|
71
|
-
if (room.assetpack.assetmap[this.assettype]) {
|
|
71
|
+
if (room.assetpack && room.assetpack.assetmap[this.assettype]) {
|
|
72
72
|
return room.assetpack.assetmap[this.assettype];
|
|
73
73
|
}
|
|
74
74
|
return {};
|
|
@@ -18,7 +18,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
18
18
|
shadow: false,
|
|
19
19
|
shadow_cast: false,
|
|
20
20
|
shadow_receive: false,
|
|
21
|
-
renderorder:
|
|
21
|
+
renderorder: 51,
|
|
22
22
|
depth_test: false,
|
|
23
23
|
depth_write: false,
|
|
24
24
|
});
|
|
@@ -31,7 +31,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
31
31
|
shadow: false,
|
|
32
32
|
shadow_cast: false,
|
|
33
33
|
shadow_receive: false,
|
|
34
|
-
renderorder:
|
|
34
|
+
renderorder: 50,
|
|
35
35
|
});
|
|
36
36
|
this.pointer = this.marker.createObject('Object', {
|
|
37
37
|
id: 'pyramid',
|
|
@@ -44,6 +44,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
44
44
|
shadow: false,
|
|
45
45
|
shadow_cast: false,
|
|
46
46
|
shadow_receive: false,
|
|
47
|
+
renderorder: 52,
|
|
47
48
|
});
|
|
48
49
|
/*
|
|
49
50
|
this.light = this.createObject('Light', {
|
|
@@ -82,7 +83,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
82
83
|
depth_write: false,
|
|
83
84
|
shadow_cast: false,
|
|
84
85
|
shadow_receive: false,
|
|
85
|
-
renderorder:
|
|
86
|
+
renderorder: 1000,
|
|
86
87
|
visible: false,
|
|
87
88
|
});
|
|
88
89
|
|
|
@@ -124,8 +125,8 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
124
125
|
});
|
|
125
126
|
this.activateControlContext('teleporter');
|
|
126
127
|
|
|
127
|
-
room.addEventListener('mousedown', (ev) => this.handleMouseDown(ev));
|
|
128
|
-
room.addEventListener('mouseup', (ev) => this.handleMouseUp(ev));
|
|
128
|
+
//room.addEventListener('mousedown', (ev) => this.handleMouseDown(ev));
|
|
129
|
+
//room.addEventListener('mouseup', (ev) => this.handleMouseUp(ev));
|
|
129
130
|
elation.events.add(janus._target, 'room_change', (ev) => this.handleRoomChange(ev));
|
|
130
131
|
},
|
|
131
132
|
update() {
|
|
@@ -153,7 +154,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
153
154
|
let laserpoints = this.laser.positions;
|
|
154
155
|
// Trace our arc in steps, performing a raytrace at each step
|
|
155
156
|
for (i = 0; i < segments; i++) {
|
|
156
|
-
let t = (i + 1) * duration / segments
|
|
157
|
+
let t = (i + 1) * duration / segments;
|
|
157
158
|
dir.copy(v0);
|
|
158
159
|
speed = dir.length();
|
|
159
160
|
dir.divideScalar(speed);
|
|
@@ -184,7 +185,7 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
this.laser.updateLine();
|
|
187
|
-
if (this.laser.room !== room) room.appendChild(this.laser);
|
|
188
|
+
if (this.laser.room !== room._target) room.appendChild(this.laser);
|
|
188
189
|
this.pointer.orientation._target.setFromEuler(new THREE.Euler(Math.PI/2, this.teleportangle, 0, "YXZ"));
|
|
189
190
|
} else {
|
|
190
191
|
if (this.shroud.visible) {
|
|
@@ -327,8 +328,8 @@ janus.registerElement('locomotion_teleporter', {
|
|
|
327
328
|
if (!room.teleport) return;
|
|
328
329
|
this.visible = true;
|
|
329
330
|
this.particles.visible = true;
|
|
330
|
-
if (this.laser.room !== room) room.appendChild(this.laser);
|
|
331
|
-
if (this.particles.room !== room) room.appendChild(this.particles);
|
|
331
|
+
if (this.laser.room !== room._target) room.appendChild(this.laser);
|
|
332
|
+
if (this.particles.room !== room._target) room.appendChild(this.particles);
|
|
332
333
|
this.laser.visible = true;
|
|
333
334
|
this.active = true;
|
|
334
335
|
this.particles.start();
|