Compare commits
No commits in common. "feat/0.0.5-rc" and "master" have entirely different histories.
feat/0.0.5
...
master
14
README.md
|
|
@ -84,17 +84,16 @@ You can override the default content (embedded in the executable).
|
|||
Extract and run example 3D content in your browser:
|
||||
|
||||
```bash
|
||||
$ unzip xrforge.com myverse/* # extract example 3D verse files
|
||||
$ ./xrforge.com server # run as server
|
||||
ℹ️ unzipping example content to folder 'myverse'
|
||||
opening your browser at https://localhost:8080
|
||||
```
|
||||
|
||||
> Play around in the browser, and launch a file-explorer with directory `myverse`, and see how directories, sidecarfiles and symlinks are used to manage interconnected virtual worlds.
|
||||
> just look around in `myverse` and get a hunch of how directories + sidecarfiles are used to manage content.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="p" id="radical">
|
||||
|
||||
## Radical opensource
|
||||
|
||||
```
|
||||
|
|
@ -117,12 +116,11 @@ Archive: result/bin/xrforge.com
|
|||
|
||||
## Adding content
|
||||
|
||||
First you need a directory with glTF or (JanusXR) JML experiences.<br>
|
||||
Luckily, running the server (`./xrforge.com server`) once will produce example-folder `myverse`.<br>
|
||||
Then run this in the terminal:
|
||||
First you need a directory with glTF or JanusXR experiences.<br>
|
||||
Just run this in the terminal:
|
||||
|
||||
```bash
|
||||
$ unzip xrforge.com myverse/* # optional: unzip example-content manually
|
||||
$ unzip xrforge.com myverse
|
||||
$ tree myverse
|
||||
myverse
|
||||
├── janusxr
|
||||
|
|
@ -140,7 +138,7 @@ myverse
|
|||
└── tronverse.png
|
||||
```
|
||||
|
||||
> optionally you can run `./xrforge.com admin` and change default directoryname (`myverse`) if needed.
|
||||
> optionally you can run `./xrforge.com admin` and change the `myverse` directory if needed.
|
||||
</div>
|
||||
|
||||
<div class="addcontent">
|
||||
|
|
|
|||
|
|
@ -83,18 +83,17 @@ app.plugin.pubnix = app.addPlugin('plugin/pubnix')
|
|||
app.plugin.diskscan = app.addPlugin('plugin/diskscan')
|
||||
app.plugin.convert = app.addPlugin('plugin/convert')
|
||||
app.plugin.moderation = app.addPlugin('plugin/moderation')
|
||||
app.plugin.desktopfile = app.addPlugin('plugin/desktopfile')
|
||||
app.plugin.xrfragments = app.addPlugin('plugin/xrfragments')
|
||||
app.plugin.janusxr = app.addPlugin('plugin/janusxr')
|
||||
app.plugin.clouddrive = app.addPlugin('plugin/clouddrive')
|
||||
app.plugin.markdown = app.addPlugin('plugin/markdown')
|
||||
app.plugin.rssatom = app.addPlugin('plugin/rssatom')
|
||||
app.plugin.federation = app.addPlugin('plugin/federation')
|
||||
app.plugin.manyfold = app.addPlugin('plugin/manyfold')
|
||||
app.plugin.peertube = app.addPlugin('plugin/peertube')
|
||||
app.plugin.git = app.addPlugin('plugin/git')
|
||||
app.plugin.webhook = app.addPlugin('plugin/webhook')
|
||||
app.plugin.archive = app.addPlugin('plugin/archive')
|
||||
app.plugin.manyfold = app.addPlugin('plugin/manyfold')
|
||||
app.plugin.openbrush = app.addPlugin('plugin/openbrush')
|
||||
app.plugin.scheduler = app.addPlugin('plugin/scheduler') -- should always be second last
|
||||
app.plugin.staticwebgen = app.addPlugin('plugin/staticwebgen') -- should always be last
|
||||
|
|
@ -109,7 +108,6 @@ print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean lo
|
|||
app.url['^/data'] = '/data.lua' -- setup custom file endpoint
|
||||
|
||||
app.use( app.plugin.global.middleware.homepage_2D_or_3D )
|
||||
app.use( app.plugin.global.middleware.force_listing )
|
||||
|
||||
app.get('^/design[/]?$', util.pagerender('page/design.html'))
|
||||
app.get('^/about[/]?$', util.pagerender('page/about.html'))
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ end
|
|||
util.readfile = function(filename, mode, silent)
|
||||
local file, err = io.open(filename, mode or "r")
|
||||
if not file then
|
||||
if not silent then print("Error opening file:", filename, err) end
|
||||
if not silent then print("Error opening file:", err) end
|
||||
return
|
||||
end
|
||||
local content = file:read("*a")
|
||||
|
|
@ -24,7 +24,7 @@ end
|
|||
util.writefile = function(filename, content, mode)
|
||||
local file, err = io.open(filename, mode or "w") -- Default write mode
|
||||
if not file then
|
||||
return print("Error opening file:", filename, err)
|
||||
return print("Error opening file:", err)
|
||||
end
|
||||
file:write(content)
|
||||
file:close()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ body.script .script{ visibility: visible !important; }
|
|||
.margin1L{ margin: 0px 20px 10px 0px;}
|
||||
.margin1{ margin: 10px 20px; }
|
||||
.padding1{ padding: 10px 20px 10px 20px; }
|
||||
.nopadding{ padding:0px;}
|
||||
|
||||
.content{
|
||||
font-family: sans-serif;
|
||||
|
|
@ -87,7 +86,6 @@ textarea{
|
|||
input[type=submit]{
|
||||
display: inline-block;
|
||||
margin: 0 15px 0px 0px;
|
||||
border: 1px dotted
|
||||
}
|
||||
|
||||
.btn a,
|
||||
|
|
@ -104,20 +102,6 @@ input[type=submit] {
|
|||
background:#112;
|
||||
}
|
||||
|
||||
.iconbtn{
|
||||
float: right;
|
||||
border: 1px solid #8880 !important;
|
||||
border-spacing: 10px 10px 10px 10px;
|
||||
padding: 0px 5px;
|
||||
border-radius: 4px;
|
||||
background: #2230;
|
||||
transition: border 0.4s;
|
||||
}
|
||||
.iconbtn:hover{
|
||||
border: 1px solid #888 !important;
|
||||
background: #223;
|
||||
}
|
||||
|
||||
.btn a:hover,
|
||||
input[type=submit] {
|
||||
color:#F7F;
|
||||
|
|
@ -206,7 +190,7 @@ h1{
|
|||
|
||||
h1 a,
|
||||
h2 a,
|
||||
.jumbotron center a{
|
||||
center a{
|
||||
text-decoration:none;
|
||||
border:none !important;
|
||||
}
|
||||
|
|
@ -220,6 +204,14 @@ table.header tr td {
|
|||
border:none;
|
||||
}
|
||||
|
||||
.btn.XR{
|
||||
line-height:10px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
/* logo */
|
||||
.logo *{
|
||||
font-size:15px;
|
||||
|
|
@ -261,7 +253,7 @@ ul{
|
|||
.grid .tile{ border-radius:5px; }
|
||||
.grid .tile .text{ padding:3px 0px; }
|
||||
.grid .tile .img{
|
||||
border-radius:13px;
|
||||
border-radius:20px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
:root{
|
||||
--gradient-1: #114,#224,#114,#3367,#424,#224;
|
||||
}
|
||||
|
||||
hr{
|
||||
display:none !important;
|
||||
}
|
||||
|
|
@ -66,7 +62,7 @@ body{
|
|||
}
|
||||
|
||||
.grid .tile .text{
|
||||
padding: 10px !important;
|
||||
padding: 10px 20px 10px 15px !important;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
|
|
@ -87,13 +83,9 @@ img.icon.list-tree{
|
|||
filter: invert(1);
|
||||
}
|
||||
img.icon.download,
|
||||
img.icon.play{
|
||||
img.icon.play,{
|
||||
transform: translate(0,-1px);
|
||||
}
|
||||
img.icon.folder,
|
||||
img.icon.file-document{
|
||||
transform: translate(0,-2px);
|
||||
}
|
||||
|
||||
img.icon.share{
|
||||
opacity:0.66;
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M7 18H17V16H7V18Z" fill="currentColor" />
|
||||
<path d="M17 14H7V12H17V14Z" fill="currentColor" />
|
||||
<path d="M7 10H11V8H7V10Z" fill="currentColor" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M6 2C4.34315 2 3 3.34315 3 5V19C3 20.6569 4.34315 22 6 22H18C19.6569 22 21 20.6569 21 19V9C21 5.13401 17.866 2 14 2H6ZM6 4H13V9H19V19C19 19.5523 18.5523 20 18 20H6C5.44772 20 5 19.5523 5 19V5C5 4.44772 5.44772 4 6 4ZM15 4.10002C16.6113 4.4271 17.9413 5.52906 18.584 7H15V4.10002Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 645 B |
|
|
@ -9,6 +9,6 @@
|
|||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M4 1.5C2.89543 1.5 2 2.39543 2 3.5V4.5C2 4.55666 2.00236 4.61278 2.00698 4.66825C0.838141 5.07811 0 6.19118 0 7.5V19.5C0 21.1569 1.34315 22.5 3 22.5H21C22.6569 22.5 24 21.1569 24 19.5V7.5C24 5.84315 22.6569 4.5 21 4.5H11.874C11.4299 2.77477 9.86384 1.5 8 1.5H4ZM9.73244 4.5C9.38663 3.9022 8.74028 3.5 8 3.5H4V4.5H9.73244ZM3 6.5C2.44772 6.5 2 6.94772 2 7.5V19.5C2 20.0523 2.44772 20.5 3 20.5H21C21.5523 20.5 22 20.0523 22 19.5V7.5C22 6.94772 21.5523 6.5 21 6.5H3Z"
|
||||
fill="currentColor"
|
||||
fill="#557"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 669 B After Width: | Height: | Size: 662 B |
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="8 10 20.396395760613586 20" width="37.396395760613586" height="40"><!-- svg-source:excalidraw --><metadata></metadata><defs></defs><g stroke-linecap="round" transform="translate(10 11.351351351351354) rotate(0 8.698197880306793 8.783783783783804)"><path d="M4.35 0 C6.69 0, 9.02 0, 13.05 0 M4.35 0 C7.1 0, 9.86 0, 13.05 0 M13.05 0 C15.95 0, 17.4 1.45, 17.4 4.35 M13.05 0 C15.95 0, 17.4 1.45, 17.4 4.35 M17.4 4.35 C17.4 6.35, 17.4 8.35, 17.4 13.22 M17.4 4.35 C17.4 7.54, 17.4 10.73, 17.4 13.22 M17.4 13.22 C17.4 16.12, 15.95 17.57, 13.05 17.57 M17.4 13.22 C17.4 16.12, 15.95 17.57, 13.05 17.57 M13.05 17.57 C9.81 17.57, 6.58 17.57, 4.35 17.57 M13.05 17.57 C10.88 17.57, 8.71 17.57, 4.35 17.57 M4.35 17.57 C1.45 17.57, 0 16.12, 0 13.22 M4.35 17.57 C1.45 17.57, 0 16.12, 0 13.22 M0 13.22 C0 11.05, 0 8.88, 0 4.35 M0 13.22 C0 10.68, 0 8.15, 0 4.35 M0 4.35 C0 1.45, 1.45 0, 4.35 0 M0 4.35 C0 1.45, 1.45 0, 4.35 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(16.756756756756772 10) rotate(0 1.899999976158142 10)"><text x="0" y="16.264000000000001" font-family="Nunito, sans-serif, Segoe UI Emoji" font-size="14px" fill="#1e1e1e" text-anchor="start" style="font-weight:bold;white-space: pre;" direction="ltr" dominant-baseline="alphabetic">i</text></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="-25 -20 100 100" style="enable-background:new 0 0 58.752 58.752;" xml:space="preserve">
|
||||
<g>
|
||||
<path stroke="#CCC5" stroke-opacity="0.5" fill="#CCC5" d="M52.524,23.925L12.507,0.824c-1.907-1.1-4.376-1.097-6.276,0C4.293,1.94,3.088,4.025,3.088,6.264v46.205
|
||||
c0,2.24,1.204,4.325,3.131,5.435c0.953,0.555,2.042,0.848,3.149,0.848c1.104,0,2.192-0.292,3.141-0.843l40.017-23.103
|
||||
c1.936-1.119,3.138-3.203,3.138-5.439C55.663,27.134,54.462,25.05,52.524,23.925z M49.524,29.612L9.504,52.716
|
||||
c-0.082,0.047-0.18,0.052-0.279-0.005c-0.084-0.049-0.137-0.142-0.137-0.242V6.263c0-0.1,0.052-0.192,0.14-0.243
|
||||
c0.042-0.025,0.09-0.038,0.139-0.038c0.051,0,0.099,0.013,0.142,0.038l40.01,23.098c0.089,0.052,0.145,0.147,0.145,0.249
|
||||
C49.663,29.47,49.611,29.561,49.524,29.612z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
|
@ -1,77 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>JanusWeb</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="janusweb.css" media="all" />
|
||||
<link rel="manifest" href="manifest.json">
|
||||
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, maximum-scale=1.0, width=device-width" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#2f363b">
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="XRForge JanusWeb" />
|
||||
<meta property="og:description" content="The World Within The Web" />
|
||||
<meta property="og:image" content="https://janusxr.com/backgrounds/wallpapers/generic.png" />
|
||||
|
||||
|
||||
<script src="janusweb.js"></script>
|
||||
<script src="media/component/janus-script-peertube/translator.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<janus-viewer src="./index.html"></janus-viewer> <!-- project this document in 3D -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!--
|
||||
|
||||
<fireboxroom>
|
||||
<assets></assets>
|
||||
<room use_local_asset="room_plane" fwd="0 0 1">
|
||||
<object js_id="links" rotation="0 180 0">
|
||||
|
||||
<link js_id="1" pos="3 0 10" xdir="-0.866027 0 0.499998" ydir="0 1 0" zdir="-0.499998 0 -0.866027" url="https://www.reddit.com/r/vrsites" col="#ffffff" scale="1.5 3 1" draw_glow="false" >
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
<link js_id="3" pos="5 0 8.5" xdir="-0.707109 0 0.707105" ydir="0 1 0" zdir="-0.707105 0 -0.707109" url="https://vesta.janusxr.org" col="#ffffff" scale="1.5 3 1" draw_glow="false">
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
<link js_id="2" pos="-3 0 10" xdir="-0.866024 0 -0.500002" ydir="0 1 0" zdir="0.500002 0 -0.866024" url="workspaces" col="#ffffff" scale="1.5 3 1" draw_glow="false">
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
<link js_id="4" pos="-5 0 8.5" xdir="-0.707106 0 -0.707108" ydir="0 1 0" zdir="0.707108 0 -0.707106" url="bookmarks" col="#ffffff" scale="1.5 3 1" draw_glow="false">
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
<link js_id="0" pos="0 0 10.8" xdir="-1 0 -0.000002" ydir="0 1 0" zdir="0.000002 0 -1" url="https://www.janusxr.org/newlobby/index.html" col="#ffffff" scale="1.5 3 1" draw_glow="false">
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
<link js_id="5" pos="-6.51 0 6.5" rotation="-180 65 -180" url="https://xrforge.isvery.ninja" col="#ffffff" scale="1.5 3 1" draw_glow="false">
|
||||
<paragraph js_id="p" width="300" height="700" pos="0 1.53 0.05" transparent="true" scale="0.7 1.68 1" lighting="false">
|
||||
<![CDATA[ <img src="media/images/portal.svg" width="300" height="700"/> ]]>
|
||||
</paragraph>
|
||||
</link>
|
||||
|
||||
</object>
|
||||
</room>
|
||||
</fireboxroom>
|
||||
|
||||
-->
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
[
|
||||
{ "assettype":"model", "name":"capsule", "src":"assets/primitives/capsule.obj" },
|
||||
{ "assettype":"model", "name":"cone", "src":"assets/primitives/cone.obj" },
|
||||
{ "assettype":"model", "name":"cube", "src":"assets/primitives/cube.obj" },
|
||||
{ "assettype":"model", "name":"cylinder", "src":"assets/primitives/cylinder.obj" },
|
||||
{ "assettype":"model", "name":"pipe", "src":"assets/primitives/pipe.obj" },
|
||||
{ "assettype":"model", "name":"plane", "src":"assets/primitives/plane.obj" },
|
||||
{ "assettype":"model", "name":"pyramid", "src":"assets/primitives/pyramid.obj" },
|
||||
{ "assettype":"model", "name":"sphere", "src":"assets/primitives/sphere.obj" },
|
||||
{ "assettype":"model", "name":"torus", "src":"assets/primitives/torus.obj" },
|
||||
|
||||
{ "assettype":"image", "name":"room1_tex0", "src":"assets/rooms/room1.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room2_tex0", "src":"assets/rooms/room2.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room3_tex0", "src":"assets/rooms/room3.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room4_tex0", "src":"assets/rooms/room4.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room5_tex0", "src":"assets/rooms/room5.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room6_tex0", "src":"assets/rooms/room6.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_1pedestal_tex0", "src":"assets/rooms/room_1pedestal.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_2pedestal_tex0", "src":"assets/rooms/room_2pedestal.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_3_narrow_tex0", "src":"assets/rooms/room_3_narrow.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_3_wide_tex0", "src":"assets/rooms/room_3_wide.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_4_narrow_tex0", "src":"assets/rooms/room_4_narrow.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_4_wide_tex0", "src":"assets/rooms/room_4_wide.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_box_small_tex0", "src":"assets/rooms/room_box_small.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_box_medium_tex0", "src":"assets/rooms/room_box_medium.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room1_new_tex0", "src":"assets/rooms/room1_new.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_home_tex0", "src":"assets/rooms/room_home.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_plane_tex0", "src":"assets/rooms/tile_d.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"room_plane2_tex0", "src":"assets/rooms/room_plane2.png", "hasalpha": false, "preload": false },
|
||||
|
||||
{ "assettype":"model", "name":"room1", "src":"assets/rooms/room1.obj", "tex0":"room1_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room2", "src":"assets/rooms/room2.obj", "tex0":"room2_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room3", "src":"assets/rooms/room3.obj", "tex0":"room3_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room4", "src":"assets/rooms/room4.obj", "tex0":"room4_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room5", "src":"assets/rooms/room5.obj", "tex0":"room5_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room6", "src":"assets/rooms/room6.obj", "tex0":"room6_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_1pedestal", "src":"assets/rooms/room_1pedestal.obj", "tex0":"room_1pedestal_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_2pedestal", "src":"assets/rooms/room_2pedestal.obj", "tex0":"room_2pedestal_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_3_narrow", "src":"assets/rooms/room_3_narrow.obj", "tex0":"room_3_narrow_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_3_wide", "src":"assets/rooms/room_3_wide.obj", "tex0":"room_3_wide_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_4_narrow", "src":"assets/rooms/room_4_narrow.obj", "tex0":"room_4_narrow_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_4_wide", "src":"assets/rooms/room_4_wide.obj", "tex0":"room_4_wide_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_box_small", "src":"assets/rooms/room_box_small.obj", "tex0":"room_box_small_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_box_medium", "src":"assets/rooms/room_box_medium.obj", "tex0":"room_box_medium_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room1_new", "src":"assets/rooms/room1_new.obj", "tex0":"room1_new_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_home", "src":"assets/rooms/room_home.obj", "tex0":"room_home_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_plane", "src":"assets/rooms/room_plane.obj", "tex0":"room_plane_tex0", "hasalpha": false },
|
||||
{ "assettype":"model", "name":"room_plane2", "src":"assets/rooms/room_plane2.obj", "tex0":"room_plane2_tex0", "hasalpha": false },
|
||||
|
||||
{ "assettype":"model", "name":"room1_collision", "src":"assets/rooms/room1_collision.obj" },
|
||||
{ "assettype":"model", "name":"room2_collision", "src":"assets/rooms/room2_collision.obj" },
|
||||
{ "assettype":"model", "name":"room3_collision", "src":"assets/rooms/room3_collision.obj" },
|
||||
{ "assettype":"model", "name":"room4_collision", "src":"assets/rooms/room4_collision.obj" },
|
||||
{ "assettype":"model", "name":"room5_collision", "src":"assets/rooms/room5_collision.obj" },
|
||||
{ "assettype":"model", "name":"room6_collision", "src":"assets/rooms/room6_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_1pedestal_collision", "src":"assets/rooms/room_1pedestal_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_2pedestal_collision", "src":"assets/rooms/room_2pedestal_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_3_narrow_collision", "src":"assets/rooms/room_3_narrow_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_3_wide_collision", "src":"assets/rooms/room_3_wide_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_4_narrow_collision", "src":"assets/rooms/room_4_narrow_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_4_wide_collision", "src":"assets/rooms/room_4_wide_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_box_small_collision", "src":"assets/rooms/room_box_small_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_box_medium_collision", "src":"assets/rooms/room_box_medium_collision.obj" },
|
||||
{ "assettype":"model", "name":"room1_new_collision", "src":"assets/rooms/room1_new_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_home_collision", "src":"assets/rooms/room_home_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_plane_collision", "src":"assets/rooms/room_plane_collision.obj" },
|
||||
{ "assettype":"model", "name":"room_plane2_collision", "src":"assets/rooms/room_plane2_collision.obj" },
|
||||
|
||||
{ "assettype":"image", "name":"black", "src":"assets/black.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"clear", "src":"assets/clear.png", "hasalpha": true, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_back", "src":"assets/skybox/dark_back.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_down", "src":"assets/skybox/dark_down.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_front", "src":"assets/skybox/dark_front.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_left", "src":"assets/skybox/dark_left.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_right", "src":"assets/skybox/dark_right.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dark_up", "src":"assets/skybox/dark_up.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_back", "src":"assets/skybox/miramar_back.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_down", "src":"assets/skybox/miramar_down.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_front", "src":"assets/skybox/miramar_front.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_left", "src":"assets/skybox/miramar_left.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_right", "src":"assets/skybox/miramar_right.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"miramar_up", "src":"assets/skybox/miramar_up.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_back", "src":"assets/skybox/skyrender_back.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_down", "src":"assets/skybox/skyrender_down.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_front", "src":"assets/skybox/skyrender_front.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_left", "src":"assets/skybox/skyrender_left.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_right", "src":"assets/skybox/skyrender_right.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"skyrender_up", "src":"assets/skybox/skyrender_up.png", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_back", "src":"assets/skybox/Day/Dayback.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_down", "src":"assets/skybox/Day/Daybottom.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_front", "src":"assets/skybox/Day/Dayfront.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_left", "src":"assets/skybox/Day/Dayleft.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_right", "src":"assets/skybox/Day/Dayright.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"dayskybox_up", "src":"assets/skybox/Day/Daytop.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_back", "src":"assets/skybox/Night/Nightback.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_down", "src":"assets/skybox/Night/Nightbottom.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_front", "src":"assets/skybox/Night/Nightfront.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_left", "src":"assets/skybox/Night/Nightleft.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_right", "src":"assets/skybox/Night/Nightright.jpg", "hasalpha": false, "preload": false },
|
||||
{ "assettype":"image", "name":"nightskybox_up", "src":"assets/skybox/Night/Nighttop.jpg", "hasalpha": false, "preload": false },
|
||||
|
||||
{ "assettype":"model", "name":"avatar", "src":"assets/avatar.obj", "tex0": "avatar_tex0" },
|
||||
{ "assettype":"model", "name":"avatar_head", "src":"assets/avatar_head.obj", "tex0": "avatar_head_tex0" },
|
||||
{ "assettype":"model", "name":"avatar_gltf", "src":"assets/janus-avatar-base.glb" },
|
||||
{ "assettype":"model", "name":"avatar_animations", "src":"assets/janus-avatar-animations.glb" },
|
||||
|
||||
{ "assettype":"image", "name":"avatar_tex0", "src":"assets/avatar.png", "preload": false },
|
||||
{ "assettype":"image", "name":"avatar_head_tex0", "src":"assets/avatar_head.png", "preload": false },
|
||||
|
||||
{ "assettype":"model", "name":"avatar_janusweb", "src":"assets/hoverscreen.obj" },
|
||||
|
||||
{ "assettype":"model", "name":"loading", "src":"assets/loading.obj" },
|
||||
|
||||
{ "assettype":"image", "name":"cursor_arrow", "src":"assets/cursor/arrow.png", "hasalpha": true },
|
||||
{ "assettype":"image", "name":"cursor_crosshair", "src":"assets/cursor/crosshair.png", "hasalpha": true },
|
||||
{ "assettype":"image", "name":"cursor_hand", "src":"assets/cursor/hand.png", "hasalpha": true },
|
||||
{ "assettype":"image", "name":"cursor_dot_inactive", "src":"assets/cursor/cursor-dot-white.png", "hasalpha": true },
|
||||
{ "assettype":"image", "name":"cursor_dot_active", "src":"assets/cursor/cursor-dot-green.png", "hasalpha": true },
|
||||
|
||||
|
||||
{ "assettype":"model", "name":"controller_daydream", "src":"assets/controllers/daydream/vr_controller_daydream.obj", "mtl":"vr_controller_daydream.mtl" },
|
||||
{ "assettype":"model", "name":"controller_vive", "src":"assets/controllers/vive/ViveController.dae.gz" },
|
||||
{ "assettype":"model", "name":"controller_touch_left", "src":"assets/controllers/oculus/TouchLeftModified.dae.gz" },
|
||||
{ "assettype":"model", "name":"controller_touch_right", "src":"assets/controllers/oculus/TouchRight.dae.gz" },
|
||||
{ "assettype":"font", "name":"helvetiker", "src":"assets/fonts/helvetiker_regular.typeface.json" },
|
||||
{ "assettype":"shader", "name":"defaultportal", "shadertype":"shadertoy","fragment_src":"assets/shaders/greenportal2.shadertoy.frag", "preload":true },
|
||||
|
||||
{ "assettype":"model", "name":"button", "src":"component/janus-script-peertube/asset/button.glb", "preload":true},
|
||||
{ "assettype":"model", "name":"icon", "src":"component/janus-script-peertube/asset/button.icon.glb", "preload":true},
|
||||
{ "assettype":"sound", "name":"button-click", "src":"component/janus-script-peertube/asset/button.click.mp3", "preload":true},
|
||||
{ "assettype":"sound", "name":"button-hover", "src":"component/janus-script-peertube/asset/button.hover.mp3", "preload":true}
|
||||
|
||||
]
|
||||
|
|
@ -1 +0,0 @@
|
|||
//alert("xrforge")
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"templates": {
|
||||
},
|
||||
"scripts": [
|
||||
"./xrforge.js"
|
||||
],
|
||||
"css": []
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"apps": {
|
||||
"navigation": "./apps/navigation/navigation.json",
|
||||
"comms": "./apps/comms/comms.json",
|
||||
"avatar": "./apps/avatar/avatar.json",
|
||||
"settings": "./apps/settings/settings.json",
|
||||
"inventory": "./apps/inventory/inventory.json",
|
||||
"editor": "./apps/editor/editor.json?v=12",
|
||||
"transporter": "./apps/transporter/transporter.json",
|
||||
"locomotion": "./apps/locomotion/locomotion.json",
|
||||
"virtualgamepad": "./apps/virtualgamepad/virtualgamepad.json",
|
||||
"buttons": "./apps/buttons/buttons.json",
|
||||
"xrmenu": "./apps/xrmenu/xrmenu.json?v=14",
|
||||
"xrfragment": "./apps/xrfragment/xrfragment.json",
|
||||
"xrforge": "./apps/xrforge/xrforge.json",
|
||||
"vfs": "./apps/vfs/vfs.json"
|
||||
},
|
||||
"includes": [
|
||||
],
|
||||
"templates": {
|
||||
"janusweb.ui": "./default.html"
|
||||
},
|
||||
"css": [
|
||||
"./themes/default.css"
|
||||
],
|
||||
"scripts": [
|
||||
]
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
const PeertubeTranslatorBaseURL = document.currentScript.src.replace("/translator.js","")
|
||||
|
||||
elation.require([], function() {
|
||||
elation.component.add('janusweb.translators.peertube', function() {
|
||||
this.init = function() {
|
||||
this.description = "peertube website to 3D translator"
|
||||
}
|
||||
this.exec = function(args) {
|
||||
return new Promise(elation.bind(this, function(resolve, reject) {
|
||||
|
||||
var room = this.room = args.room;
|
||||
|
||||
reject() // for now
|
||||
|
||||
this.setupEvents()
|
||||
var datapath = elation.config.get('janusweb.datapath', '/media/janusweb');
|
||||
|
||||
var roomdata = {
|
||||
assets: {
|
||||
assetlist: [
|
||||
// {assettype: 'model', name: 'scene', src: args.url},
|
||||
]
|
||||
},
|
||||
room: {
|
||||
pos: [0,0,0],
|
||||
xdir: "1 0 0",
|
||||
zdir: "0 0 1",
|
||||
},
|
||||
object: [
|
||||
// {id: 'scene', js_id: 0, pos: "0 0 0", xdir: "-1 0 0", zdir: "0 0 -1", lighting: "false"}
|
||||
],
|
||||
link: []
|
||||
};
|
||||
resolve(roomdata);
|
||||
}));
|
||||
}
|
||||
|
||||
// translate XR Fragments microformat into JML
|
||||
this.parseSource = async function(sourcecode, room){
|
||||
this.room = room
|
||||
const isJML = /<fireboxroom>[\s\S]*?<\/fireboxroom>/si;
|
||||
const isPeertube = /<meta\s+[^>]*property=['"]og:platform['"]\s+[^>]*content=['"]peertube['"][^>]*\/?>/si;
|
||||
const isPeertubeVideo = /<meta\s+[^>]*property=['"]og:type['"]\s+[^>]*content=['"]video['"][^>]*\/?>/si;
|
||||
const isPeertubeInstance = /<meta\s+[^>]*property=['"]og:type['"]\s+[^>]*content=['"]website['"][^>]*\/?>/si;
|
||||
const is = {
|
||||
JML: sourcecode.match(isJML),
|
||||
peertube: sourcecode.match(isPeertube),
|
||||
peertubeVideo: sourcecode.match(isPeertubeVideo),
|
||||
peertubeInstance: sourcecode.match(isPeertubeInstance),
|
||||
}
|
||||
if( is.JML || !is.peertube ) return // JML takes precedence over microformats
|
||||
if( !is.peertubeVideo && !is.peertubeInstance ) return
|
||||
|
||||
// ok..peertube time: get domtree
|
||||
let el = document.createElement("div")
|
||||
el.innerHTML = sourcecode
|
||||
|
||||
// try to fetch title + cover
|
||||
const title = el.querySelector("title")
|
||||
let logo = el.querySelector("meta[property='og:image']")?.getAttribute("content")
|
||||
logo = logo ? logo : el.querySelector("meta[property='og:image:url']")?.getAttribute("content")
|
||||
|
||||
let url = new URL( String(room.url) )
|
||||
let instance = url?.origin
|
||||
let search = url?.search ? new URLSearchParams(url.search).get("search") : ""
|
||||
|
||||
room.corsproxy = ''
|
||||
// return JML
|
||||
let parsed = room.parseSource(`
|
||||
<title>${ title ? title.innerText.replace(/\n.*/g,'') : room.baseurl.split("/").pop() }</title>
|
||||
<FireBoxRoom>
|
||||
<Assets>
|
||||
${ logo ? `<assetimage src="${logo}" id="logo"/>` : ''}
|
||||
<assetscript src="${PeertubeTranslatorBaseURL}/janus-script-peertube.js" proxy="false"/>
|
||||
</Assets>
|
||||
<Room use_local_asset="room5" pos="1.15 0 -5">
|
||||
${ is.peertubeInstance ? `<peertube-app pos="4.55 2.71 0" scale="2 2 1" rotation="0 90 0" js_id="mypeertube-app" instance="${instance}" ${search?`search="${search}"`:``} autoload="true"/>`
|
||||
: `<peertube pos="4.55 2.71 0" scale="2 2 1" rotation="0 90 0" js_id="peertube" src="${room.url}" auto_play="true"/>`
|
||||
}
|
||||
<object position='12.2 0 0' rotation="0 -90 0">
|
||||
${ logo ? `<image id="logo" pos='0 5 0' scale='3 3 2' lighting="false" />` : ''}
|
||||
<text text="${room.url.replace(/.*:\/\//,'')}" pos='0 1.45 0' scale='7 7 7' lighting="false" col='#000000'/>
|
||||
<text text="Peertube" pos='0 8.6 0' scale='4 4 4' lighting="false" col='#000000'/>
|
||||
</object>
|
||||
</Room>
|
||||
</FireBoxRoom>
|
||||
`)
|
||||
return parsed
|
||||
}
|
||||
// peertube microformat heuristic: <meta property="og:platform" content="PeerTube">
|
||||
this.parseSource.regex = /<meta\s+[^>]*property=['"]og:platform['"]\s+[^>]*content=['"]peertube['"][^>]*\/?>/si;
|
||||
});
|
||||
});
|
||||
|
||||
elation.events.add(null, 'room_translator_register', function(e){
|
||||
const room = e.element
|
||||
const translators = e.data.translators
|
||||
// prepend translator
|
||||
e.data.translators = {}
|
||||
e.data.translators['!peertube'] = elation.janusweb.translators.peertube({janus: janus})
|
||||
for( let i in translators ){
|
||||
e.data.translators[i] = translators[i]
|
||||
}
|
||||
})
|
||||
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
|
@ -4,5 +4,3 @@
|
|||
This basically extends [the seamless JanusXR portalsystem](https://coderofsalvation.github.io/janus-guide/#/home/about) by <b>interconnecting</b> otherwise immersively-disjointed ecosystems like [AFRAME](https://aframe.io), by [reprojecting them in 3D](https://coderofsalvation.github.io/janus-guide/#/home/about).
|
||||
|
||||
Currently only geometry markup and models are supported.
|
||||
|
||||
> This example renders a local AFRAME URL
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
1
src/myverse/janusxr_tutorial/tronverse.png
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../tronverse.png
|
||||
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
|
@ -1,61 +0,0 @@
|
|||
<h1>Hi there! 👋</h1>
|
||||
Welcome to this XR experience.<br/>
|
||||
<br/>
|
||||
<div class="btn script">
|
||||
<button class="btn secondary" onclick="document.querySelector('#tips').style.display = ''">Tips for navigating in XR</button>
|
||||
</div>
|
||||
|
||||
<div id="tips" style="display:none">
|
||||
<br/>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Keyboard+Mouse</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="200">
|
||||
<b>AR/VR headset</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around / use right-longpinch (or thumbstick) for local teleports<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneVR</b>
|
||||
</td>
|
||||
<td>
|
||||
use gaze or bluetooth/mouse to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneAR</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around and tap screen to click
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Mobile</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
You've got this!
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Here's a demo to surf <a href="https://icosa.gallery/collections" target="_blank">icosa-gallery</a> immersively (without launching the website, <a href="https://openbrush.app" target="_blank">OpenBrush</a> or <a href="https://openblocks.app" target="_blank">OpenBlocks</a>).<br>
|
||||
This is possible thanks to icosa-gallery supporting the <a href="https://xrfragment.org/#XRF%20microformat" target="_blank">XR Fragments microformat</a>.
|
||||
<br>
|
||||
> <b>NOTE</b>: most example assets are not optimized regarding scale/position/floor (but can be done in OpenBrush, OpenBlocks or Blender)
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=icosa gallery
|
||||
URL=https://icosa.gallery/collections/LSc_DPROGR8
|
||||
|
|
@ -1 +0,0 @@
|
|||
AFRAME.jpg
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=AFRAME remote example
|
||||
URL=https://aframe.io/aframe/examples/boilerplate/hello-world/
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# AFRAME hello world
|
||||
|
||||
[XRForge's](https://xrforge.isvery.ninja/) [JanusXR](https://coderofsalvation.github.io/janus-guide/)-viewer ([janusweb](https://github.com/jbaicoianu/janusweb)) can detect [AFRAME](https://aframe.io) markup in HTML/XML/even binary files(!).
|
||||
This basically extends [the seamless JanusXR portalsystem](https://coderofsalvation.github.io/janus-guide/#/home/about) by <b>interconnecting</b> otherwise immersively-disjointed ecosystems like [AFRAME](https://aframe.io), by [reprojecting them in 3D](https://coderofsalvation.github.io/janus-guide/#/home/about).
|
||||
|
||||
Currently only geometry markup and models are supported.
|
||||
|
||||
> This example renders a remote AFRAME URL
|
||||
|
Before Width: | Height: | Size: 27 KiB |
|
|
@ -1,5 +0,0 @@
|
|||
# ARwindow
|
||||
|
||||
This is an AR-experience which demonstrates a 'hidden' plane (with cutout),<br>
|
||||
which creates the illusion of a VR-in-AR.<br>
|
||||
A great usecase is displaying VR (glTF) animations with variable immersion.
|
||||
|
Before Width: | Height: | Size: 42 KiB |
|
|
@ -1,5 +0,0 @@
|
|||
Demo of [XR Movies](https://xrfragment.org/#XR%20Movies%20%26%20books) using XR Fragments
|
||||
|
||||
* [default spawnpoint](https://xrfragment.org/#default%20spawn%20location)
|
||||
* [WebVTT](https://xrfragment.org/#WebVTT%20subtitles) subtitles
|
||||
* [href](https://xrfragment.org/#href) links/portals
|
||||
|
|
@ -1 +0,0 @@
|
|||
test.xrf.png
|
||||
|
Before Width: | Height: | Size: 1 MiB |
|
|
@ -1,27 +0,0 @@
|
|||
WEBVTT
|
||||
|
||||
00:01.000 --> 00:04.000 href:#spawn
|
||||
<v welcome> to a special experience.
|
||||
|
||||
00:06.000 --> 00:10.000
|
||||
This is a special place..
|
||||
|
||||
00:11.000 --> 00:16.000 href:#platformA
|
||||
A place to learn..
|
||||
|
||||
00:20.000 --> 00:25.000 href:#platformB
|
||||
A place to reflect..
|
||||
|
||||
|
||||
00:30.000 --> 00:33.000 href:#spawn_divine
|
||||
Lets go inside..
|
||||
|
||||
00:36.000 --> 00:39.000 href:#inside
|
||||
Here we are..
|
||||
|
||||
00:45.000 --> 00:48.000
|
||||
Let's visit portals..
|
||||
|
||||
00:50.000 --> 00:57.000 href:#spawn
|
||||
Try the portals on your left..
|
||||
|
||||
|
Before Width: | Height: | Size: 337 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 170 KiB |
1
src/myverse/tronverse/janusxr
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../janusxr
|
||||
|
Before Width: | Height: | Size: 315 KiB After Width: | Height: | Size: 315 KiB |
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
<h1>Hi there! 👋</h1>
|
||||
Welcome to the [VAPORWAVE PLAZA】ぼをが
|
||||
<br/>
|
||||
<div class="btn script">
|
||||
<button class="btn secondary" onclick="document.querySelector('#tips').style.display = ''">Tips for navigating in XR</button>
|
||||
</div>
|
||||
|
||||
<div id="tips" style="display:none">
|
||||
<br/>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Keyboard+Mouse</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="200">
|
||||
<b>AR/VR headset</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around / use right-longpinch (or thumbstick) for local teleports<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneVR</b>
|
||||
</td>
|
||||
<td>
|
||||
use gaze or bluetooth/mouse to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneAR</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around and tap screen to click
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Mobile</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
You've got this!
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Variation of: https://vesta.janusxr.org/virtualplaza/welcome-to-the-virtual-plaza
|
||||
|
||||
Updated with fixed links, works with the newer software.
|
||||
|
||||
#vaporwave #aesthetic
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=VaporWave Plaza
|
||||
URL=https://vesta.janusxr.org/spyduck/vaporwave-plaza
|
||||
|
Before Width: | Height: | Size: 457 KiB |
|
|
@ -1,57 +0,0 @@
|
|||
<h1>Hi there! 👋</h1>
|
||||
Welcome to Vesta Worlds,
|
||||
<br/>
|
||||
<div class="btn script">
|
||||
<button class="btn secondary" onclick="document.querySelector('#tips').style.display = ''">Tips for navigating in XR</button>
|
||||
</div>
|
||||
|
||||
<div id="tips" style="display:none">
|
||||
<br/>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Keyboard+Mouse</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="200">
|
||||
<b>AR/VR headset</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around / use right-longpinch (or thumbstick) for local teleports<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneVR</b>
|
||||
</td>
|
||||
<td>
|
||||
use gaze or bluetooth/mouse to navigate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>PhoneAR</b>
|
||||
</td>
|
||||
<td>
|
||||
walk around and tap screen to click
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Mobile</b>
|
||||
</td>
|
||||
<td>
|
||||
use the WASD-keys and mousedrag to navigate
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
You've got this!
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
VESTA is a social network for JanusXR experiences. Share, explore and create 3D worlds, games and videos with your friends across multiple metaverses.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=Vesta Worlds
|
||||
URL=https://vesta.janusxr.org
|
||||
|
Before Width: | Height: | Size: 26 KiB |
|
|
@ -6,7 +6,7 @@ header h2{
|
|||
font-weight: normal;
|
||||
}
|
||||
header{
|
||||
background-image: linear-gradient(0deg,#0000,#101,#0000), url(myverse/tech-demos/tronverse/tron/tron.png);
|
||||
background-image: linear-gradient(0deg,#0000,#101,#0000), url(myverse/tronverse/tron/tron.png);
|
||||
background-position-x: 0%;
|
||||
background-position-y: 0%;
|
||||
background-repeat: repeat;
|
||||
|
|
@ -61,8 +61,8 @@ div#xrecosystem{
|
|||
<div id="logo"></div>
|
||||
<h2>Turn files into AR/VR 🥽 experiences</h2>
|
||||
<center>
|
||||
A <b>Virtual Worlds Mixer</b> (VWM), powered by <a href="https://coderofsalvation.github.io/janus-guide">JanusXR</a> & <a href="https://xrfragment.org">XR Fragments</a>.<br>
|
||||
A static website generator for interconnected XR experiences.<br>
|
||||
Generate and manage open virtual worlds, powered by <a href="https://coderofsalvation.github.io/janus-guide">JanusXR</a> & <a href="https://xrfragment.org">XR Fragments</a>.
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="btn">
|
||||
|
|
@ -95,7 +95,7 @@ div#xrecosystem{
|
|||
<h3>What is it</h3>
|
||||
An open, seamless XR web built from simple URLs and directories, without gatekeepers.<br>
|
||||
|
||||
XRForge transforms standard local or remote file directories into interconnected 3D spaces. Users can seamlessly "surf" spatial webs (plural!), turning everyday directories and URLs into 3D portals.<br>
|
||||
XRForge transforms standard local or remote file directories into interconnected 3D spaces. Users can seamlessly "surf" spatial webs (plural!), turning everyday directories into 3D portals.<br>
|
||||
|
||||
<!--
|
||||
Supported fileformats:
|
||||
|
|
@ -117,8 +117,10 @@ div#xrecosystem{
|
|||
<div>
|
||||
In short: scalable <b>spatial blog/wiki's</b> (using plain web URLs) interconnected via <b>3D portals</b>; bringing <b>existing 2D ecosystems into XR.</b><br>
|
||||
How? Well it's backed by <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR-</a> and <a href="https://xrfragment.org" target="_blank">XR Fragment- URLs</a>.<br>
|
||||
The metaverse hype has shown: people <b>like 3D</b> but certain <b>existing</b> 2D ecosystems are king.<br>
|
||||
XRForge makes things more cost-efficient by <b>projecting existing 2D ecosystems</b> as virtual <b>hyperlinked</b> worlds, via <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a> translators, tapping into various
|
||||
The metaverse has shown: people <b>like 3D</b> but certain <b>existing</b> 2D ecosystems are king.<br>
|
||||
They're just more cost-efficient to use.<br>
|
||||
Hence, XRForge incorporates the opensource <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a>-client called <a href="https://github.com/jbaicoianu/janusweb" target="_blank">JanusWeb</a>, which promotes <b>projecting these ecosystems</b> as virtual <b>hyperlinked</b> worlds (via XR translators).<br>
|
||||
XRForge can seed itself via local or remote
|
||||
<u tabindex="0">datastores
|
||||
<span>
|
||||
<br>
|
||||
|
|
@ -127,8 +129,6 @@ div#xrecosystem{
|
|||
<br>
|
||||
<table class="table table-dark table-striped">
|
||||
<tr><td>
|
||||
<a href="https://icosa.gallery">Icosa.gallery</a><br>
|
||||
<a href="https://mayfold.app">Manyfold</a><br>
|
||||
Azure Blob <br>
|
||||
Azure Files <br>
|
||||
B2 <br>
|
||||
|
|
@ -224,9 +224,9 @@ div#xrecosystem{
|
|||
<div>
|
||||
<h3 id="autocompose">Auto-compose virtual worlds</h3>
|
||||
|
||||
Instead of manually composing virtual worlds from multiple assets, XRForge's allows mixing 3D content via <b>auto-layout</b>, <b>symbolic/online links</b>, and <b>interoperability</b>.<br>
|
||||
This means that existing RSS/Atom-feeds (from blogs), partial content from websites, and 3D scenes can be projected as virtual worlds.<br/>
|
||||
But also assets produced elsewhere, 3D scenes in <a href="https://openblocks.app" target="_blank">OpenBlocks</a> or <a href="https://openbrush.app" target="_blank">OpenBrush</a> are synchronized (via online 3D stores like <a href="https://icosa.gallery" target="_blank">icosa.gallery-</a> and <a href="https://manyfold.app" target="_blank">manyfold.app</a>).<br>
|
||||
Instead of manually composing virtual worlds from multiple assets, XRForge's philosophy is <b>auto-layout</b> and <b>interoperability</b>.<br>
|
||||
This means that existing RSS/Atom-feeds (from blogs) and partial content from websites can be projected into virtual worlds, <b>via URLs</b>.<br/>
|
||||
But also assets produced elsewhere, in <a href="https://openblocks.app" target="_blank">OpenBlocks</a> or <a href="https://openbrush.app" target="_blank">OpenBrush</a> are synchronized (via online 3D stores like <a href="https://icosa.gallery" target="_blank">icosa.gallery-</a> and <a href="https://manyfold.app" target="_blank">manyfold.app</a>).<br>
|
||||
This allows for infinitely scalable virtual worlds, yet completely downloadable and portable.<br>
|
||||
XRForge features <b>layout-engines</b> which allows <b>crowdsourcing virtual worlds</b> via assets using various apps/platforms:<br>
|
||||
<br>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ ${header}
|
|||
|
||||
{if parent ~= nil and parent.parent == nil then
|
||||
print([[
|
||||
<div style="min-height:45px;" class="jumbotron">
|
||||
<div style="height:90px;" class="jumbotron">
|
||||
<h1 style="display:none">${opts.plugin_global_title}</h1>
|
||||
<br>
|
||||
<center class="col3">
|
||||
|
|
@ -11,7 +11,7 @@ ${header}
|
|||
]])
|
||||
if opts.plugin_rssatom_mastodonshare == 'enabled' then
|
||||
print([[
|
||||
<a class="script" onclick="alert('To start receiving the (RSS) feed (of this page) in mastodon,\nwe will guide you to create an activation-post'); let instance = prompt('Your mastodon instance:', 'mastodon.social'); if( instance ){ document.location.href = 'https://' + instance + '/share?text=follow+this+XRForge+instance+]] .. util.getURL('/') .. [[index.rss+via+@birb@rss-parrot.net' } "><img src="img/mastodon.svg" class="icon mastodon"/></a>
|
||||
<a class="script" onclick="alert('To start receiving the (RSS) feed (of this page),\nwe will guide you to create an activation-post'); document.location.href = 'https://' + prompt('Your mastodon instance:', 'mastodon.social') + '/share?text=follow+this+XRForge+instance+]] .. util.getURL('/') .. [[index.rss+via+@birb@rss-parrot.net'"><img src="img/mastodon.svg" class="icon mastodon"/></a>
|
||||
]])
|
||||
end
|
||||
print([[
|
||||
|
|
@ -24,17 +24,6 @@ ${header}
|
|||
]])
|
||||
end}
|
||||
|
||||
{if isroot or url:match("/dir$") then
|
||||
local url = urlpath:gsub("/dir$","")
|
||||
print("<center>")
|
||||
if app.arg[1] == "generate" then
|
||||
print([[<div class="btn XR"><a class="border secondary" href="janusweb/#janus.url=]] .. url .. [[&janus.referrer=${referrer}">Enter XR</a></div> ]])
|
||||
else
|
||||
print([[<div class="btn XR"><a class="border secondary" href="]]..url..[[?view=3D">Enter XR</a></div> ]])
|
||||
end
|
||||
print("</center><br/>")
|
||||
end}
|
||||
|
||||
{if parent ~= nil and parent.parent ~= nil then
|
||||
print([[
|
||||
<h2><span class="col1">//</span> ${parent.name} <a href="${req.url}.rss"><img src="img/rss.svg" class="icon rss"/></a>
|
||||
|
|
@ -45,33 +34,16 @@ end}
|
|||
]])
|
||||
end
|
||||
print('</h2>')
|
||||
|
||||
if parent.info then
|
||||
print(parent.info .. [[
|
||||
<br/>
|
||||
<h2><span class="col1">//</span> assets</h2>
|
||||
<br/>
|
||||
]])
|
||||
end
|
||||
end}
|
||||
|
||||
<div class="grid">
|
||||
{if items then
|
||||
|
||||
function getURL(url, item)
|
||||
item = item or {}
|
||||
local playable = item.view3D
|
||||
or (item.janusxr and item.janusxr.room)
|
||||
or (item.redirect)
|
||||
if app.arg[1] == 'generate' then
|
||||
if playable or url:match("://") then
|
||||
url = 'janusweb/#janus.url=' .. EscapeFragment( url )
|
||||
end
|
||||
function getURL(url)
|
||||
if app.arg[1] == 'generate' or url:match("://") then
|
||||
url = '?view=3D#janus.url=' .. EscapeFragment( url )
|
||||
url = util.baseURLify(url)
|
||||
else
|
||||
if url:match("://") then
|
||||
url = '?view=3D#janus.url=' .. EscapeFragment( url )
|
||||
end
|
||||
url = util.stripPath( url )
|
||||
end
|
||||
return url
|
||||
|
|
@ -81,48 +53,16 @@ end}
|
|||
local item = items[i]
|
||||
local visible = item.view2D == nil or (item.view2D ~= nil and item.view2D ~= false)
|
||||
if visible then
|
||||
local childrenAsDir = false
|
||||
local playable = false
|
||||
local icon = false
|
||||
local url = item.markup and item.parent.url or item.url
|
||||
local thumbnail = item.markup and (item.parent.thumbnail or '') or ''
|
||||
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. '), linear-gradient(45deg,var(--gradient-1));"' end
|
||||
if item.view3D
|
||||
or (item.janusxr and item.janusxr.room)
|
||||
or (item.redirect)
|
||||
then
|
||||
playable = true
|
||||
url = url .. '?view=3D'
|
||||
icon = 'play'
|
||||
if #item.thumbnail > 0 then
|
||||
thumbnail = 'style="background-image: url(./img/playcover.svg), url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. '), linear-gradient(45deg,var(--gradient-1));"'
|
||||
else
|
||||
thumbnail = 'style="background-image: url(./img/playcover.svg), linear-gradient(45deg,var(--gradient-1));"'
|
||||
end
|
||||
end
|
||||
local icon = 'list-tree'
|
||||
local thumbnail = ''
|
||||
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. ');"' end
|
||||
if item.view3D or item.portal3D == false then icon = 'play' end
|
||||
print([[
|
||||
<div class="tile">
|
||||
<a href="]] .. getURL(item.url) .. [[">
|
||||
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
||||
<div class="text">
|
||||
]] .. ( icon and '<img src="img/' .. icon .. '.svg" class="icon ' .. icon .. '"/>' or '') .. [[<a href="]] .. getURL(item.url) .. [[">]] .. item.title .. [[</a>
|
||||
]]
|
||||
..
|
||||
( ((#item.children > 0 and not playable) or (playable and #item.children > 1)) and
|
||||
[[
|
||||
<span class="col3" style="float:right">[]] .. #item.children .. [[]</span>
|
||||
]] or ''
|
||||
)
|
||||
..
|
||||
( (item.info or (playable and #item.children > 1 and (item.janusxr and item.janusxr.layout))) and
|
||||
[[
|
||||
<a href="]] .. getURL(item.url) .. '/dir' .. [[" class="iconbtn">
|
||||
<img src="img/file-document.svg" class="icon file-document nopadding"/>
|
||||
</a>
|
||||
]] or ''
|
||||
)
|
||||
..
|
||||
[[
|
||||
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. getURL(item.url) .. [[">]] .. item.title .. [[</a>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -136,13 +76,13 @@ end}
|
|||
local icon = 'link'
|
||||
local thumbnail = ''
|
||||
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. ');"' end
|
||||
if item.view3D then icon = 'play' end
|
||||
if item.view3D or item.portal3D == false then icon = 'play' end
|
||||
print([[
|
||||
<div class="tile">
|
||||
<a href="]] .. getURL(item.url) .. [[">
|
||||
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
||||
<div class="text">
|
||||
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/><a href="]] .. getURL(item.url) .. [[">]] .. util.truncate(item.title) .. [[</a>
|
||||
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. getURL(item.url) .. [[">]] .. util.truncate(item.title) .. [[</a>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ return {
|
|||
-- add extra metadata for janusxr JML (janusxr.html and dir.html)
|
||||
table.insert(data.items, util.merge({x = i*2, i = i},v) )
|
||||
i=i+1
|
||||
if v.view3D and req.param.view ~= '2D' then
|
||||
if v.view3D then
|
||||
local isMarkupExperience = function(v)
|
||||
v = v or {}
|
||||
return v.janusxr and v.janusxr.wrap
|
||||
|
|
@ -91,26 +91,18 @@ return {
|
|||
-- *TODO* modularize this logic into plugins better
|
||||
|
||||
-- prioritize markup experience above binary 3D files as experience containers
|
||||
local notinroot = v.parent.parent ~= nil
|
||||
if notinroot and data.item == nil
|
||||
or (isMarkupExperience(v)
|
||||
and not isMarkupExperience(data.item))
|
||||
then
|
||||
if data.item == nil or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
|
||||
-- update referrer url
|
||||
data.referrer = util.baseURLify(v.view3D and (v.parent.parent and v.parent.parent.url) or v.parent.url)
|
||||
data.item = v
|
||||
data.title = data.item.title
|
||||
data.parent = v.parent
|
||||
-- *TODO* modularize this logic into plugins better
|
||||
data.janusurl = v.url
|
||||
if not data.janusurl:match("://") then
|
||||
data.janusurl = (v.janusxr and v.janusxr.wrap) and app.opts.baseurl .. util.stripPath(v.url)
|
||||
-- if parent has redirect to item set, use parent url
|
||||
if not data.janusurl or v.parent.redirect == v.url then
|
||||
data.janusurl = app.opts.baseurl .. util.stripPath(v.parent.redirect or v.parent.url)
|
||||
data.janusurl = app.opts.baseurl .. util.stripPath(v.parent.redirect)
|
||||
end
|
||||
end
|
||||
|
||||
if v.janusxr and v.janusxr.wrap and v.janusxr.wrap.file then
|
||||
-- what to do here? no generated portals?
|
||||
data.janusxr = app.tpl( util.readfile(v.path), data )
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@
|
|||
-- janusweb workaround (it does not support '/' url somehow)
|
||||
urlpath = urlpath .. app.opts.plugin_diskscan_dirname
|
||||
end
|
||||
if app.arg[1] == "generate" then
|
||||
print([[<div class="btn XR"><a class="border secondary" href="janusweb/#janus.url=]] .. urlpath .. [[&janus.referrer=${referrer}">3D</a></div> ]])
|
||||
else
|
||||
print([[<div class="btn XR"><a class="border secondary" href="${urlpath}?view=3D">3D</a></div> ]])
|
||||
end
|
||||
end}
|
||||
{if template == "page/index.html" or defined(item) then
|
||||
print([[
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ else
|
|||
description = opts.plugin_global_popup_instructions
|
||||
end}
|
||||
|
||||
{if true then
|
||||
playable = itemdir.view3D or (itemdir.janusxr and itemdir.janusxr.room) or (itemdir.redirect)
|
||||
end}
|
||||
|
||||
<div id="popup" class="content">
|
||||
<div class="spectrum span" style="top:-1px">
|
||||
<div></div>
|
||||
|
|
@ -26,13 +22,6 @@ end}
|
|||
</noscript>
|
||||
<img src="img/close.svg" width="20" class="icon close" onclick="document.querySelector('#popup').style.display = 'none'"/>
|
||||
${description}
|
||||
{if playable and #itemdir.children > 1 and (itemdir.janusxr and itemdir.janusxr.layout) then
|
||||
print([[
|
||||
<div class="btn">
|
||||
<a href="]] .. util.baseURLify( itemdir.url .. '/dir' ) .. [[">view assets ⮩</a>
|
||||
</div>
|
||||
]])
|
||||
end}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ end}
|
|||
|
||||
function initRoom(r)
|
||||
if r.janusxr and r.janusxr.room then
|
||||
pos = '0 0 2' -- todo make startup location configurable
|
||||
pos = '0 0 1' -- todo make startup location configurable
|
||||
room = r.janusxr.room
|
||||
end
|
||||
end
|
||||
initRoom(item or {})
|
||||
initRoom(itemdir or {})
|
||||
|
||||
if (hasWrapperfile == true) or (defined(item) and item.xrfragments and item.xrfragments.href) then
|
||||
if (hasWrapperfile == true) or (defined(item) and item.tag.xrfragments and item.tag.xrfragments.href) then
|
||||
room = '' -- xrfragments 3D files dont need to be wrapped with room
|
||||
end
|
||||
print(' <room skybox="true" pos="' .. pos .. '" showavatar="false" use_local_asset="' .. room .. '">')
|
||||
|
|
@ -72,16 +72,16 @@ end}
|
|||
<!-- <light js_id="dan9-janus:light/light_cone_angle=0-6" pos="0 3 2" collision_trigger="false" /> -->
|
||||
<text js_id="location" pos="0 6 -5" billboard="y" col="#BBFFFF" scale="10 10 1" text="${url}" emissive="0 0 0" roughness="0.3" metalness="0" />
|
||||
{if not defined(item) and defined(items) and #items > 0 then
|
||||
local layout = (itemdir.janusxr and itemdir.janusxr.layout) or ''
|
||||
if #layout > 0 and app.plugin.global.layout[ layout ] then
|
||||
print( app.plugin.global.layout[ layout ].lib.render(items) )
|
||||
local layout = itemdir.layout or ''
|
||||
if #layout > 0 and app.plugin.janusxr.layout[ layout ] then
|
||||
print( app.plugin.janusxr.layout[ layout ].render(items) )
|
||||
else
|
||||
print( app.plugin.global.layout.portals.lib.render(items) )
|
||||
print( app.plugin.janusxr.layout.portals.render(items) )
|
||||
end
|
||||
end}
|
||||
{if not defined(item) and defined(itemsremote) and #itemsremote > 0 then
|
||||
for i,v in pairs(itemsremote) do
|
||||
local width = (v.janusxr and v.janusxr.portal_width) or tonumber( app.opts.plugin_global_portal_width )
|
||||
local width = v.portal_width or tonumber( app.opts.plugin_global_portal_width )
|
||||
local center = -((#itemsremote*width)/1.3) + (i*width)
|
||||
local url = v.url
|
||||
local thumb = ' shader_id="defaultportal" round="true"'
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
local util = require('util')
|
||||
|
||||
app.on('scan_experience', function(exp) end)
|
||||
|
||||
app.on('scan_experience_file', function(exp)
|
||||
if exp.path:lower():match('.desktop$') then
|
||||
local data = (util.readfile( exp.path ) or '')
|
||||
local valid = false
|
||||
|
||||
foreach( util.split(data, '\n'), function(k,line)
|
||||
if line:match("^Name=") then
|
||||
exp.title = line:gsub('^Name=','')
|
||||
valid = true
|
||||
end
|
||||
if line:match("^URL=") then
|
||||
exp.url = line:gsub('^URL=','')
|
||||
valid = true
|
||||
end
|
||||
end)
|
||||
|
||||
if valid then
|
||||
exp.path = exp.path:gsub('%.desktop','')
|
||||
exp.name = exp.name:gsub('%.desktop',''):gsub("-",' ')
|
||||
--exp.dir = true
|
||||
--exp.view3D = 100
|
||||
app.markViewable(exp, 300)
|
||||
app.addExperience(exp, exp.file.ino)
|
||||
print("✅ └─ plugin/desktopfile: detected URL")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
app.on('set', function(k,v) end)
|
||||
app.on('init', function() end)
|
||||
|
||||
-- this registers the plugin UI
|
||||
local plugin = {
|
||||
name = 'Desktop files',
|
||||
hide = true,
|
||||
info = '',
|
||||
opts = {
|
||||
}
|
||||
}
|
||||
|
||||
return plugin
|
||||
|
|
@ -12,13 +12,8 @@ app.on('init', function()
|
|||
end
|
||||
else
|
||||
if not util.fileExist(app.opts.plugin_diskscan_dir) then
|
||||
if app.opts.plugin_diskscan_dirname == 'myverse' and util.cmdExist("unzip") then
|
||||
print("ℹ️ unzipping example content to folder 'myverse'")
|
||||
os.execute("unzip " .. argv[-1] .. ' "myverse/*"')
|
||||
else
|
||||
print("ℹ️ serving " .. app.opts.plugin_diskscan_dir .. " from internal (executable)")
|
||||
app.opts.plugin_diskscan_dir = '/zip/' .. util.stripPath(app.opts.plugin_diskscan_dir)
|
||||
end
|
||||
app.set('app.opts', app.opts)
|
||||
end
|
||||
end
|
||||
|
|
@ -84,8 +79,6 @@ return {
|
|||
v.file.state = nil
|
||||
end
|
||||
end)
|
||||
-- make sure to attach children-array to parents
|
||||
me.addChildren()
|
||||
|
||||
-- sort & apply dirs to plugin options
|
||||
table.sort( app.cache.dirs)
|
||||
|
|
@ -138,16 +131,26 @@ return {
|
|||
--local already_seen = seen[ino] and seen[ino].parent.file.ino == experience.parent.file.ino and true or false -- process once
|
||||
--if already_seen and not experience.symlink then return end
|
||||
|
||||
me.checkSideCarThumbnail(experience)
|
||||
|
||||
-- found directory
|
||||
if not me.shouldHideFile(name) and
|
||||
( (kind == unix.DT_DIR and kind ~= unix.DT_LNK) or experience.dir )
|
||||
then
|
||||
print("✅ ".. fullpath )
|
||||
experience.dir = true
|
||||
experience.portal3D = true -- can be viewed as 3d portal
|
||||
app.pub("scan_experience", nil, experience)
|
||||
app.addExperience(experience,ino)
|
||||
-- check for directory thumbnail sidecarfile
|
||||
local thumbExt = {"png","jpg","webp"}
|
||||
foreach( thumbExt, function(k,ext)
|
||||
local files = { fullpath .. '.' .. ext, fullpath .. '/' .. name .. '.' .. ext }
|
||||
foreach( files, function(kk,thumbnailFile)
|
||||
if util.fileExist( thumbnailFile ) then
|
||||
experience.thumbnail = "/" .. util.stripPath(thumbnailFile)
|
||||
print("✅ └─ plugin/diskscan: detected .".. ext:lower() .. " thumbnail file: " .. thumbnailFile)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
-- scan children
|
||||
me.scanDir(fullpath,experience,seen,symlinks)
|
||||
end
|
||||
|
|
@ -171,32 +174,5 @@ return {
|
|||
dref, derr = dir.foreach( scandir, scanFile )
|
||||
if not derr then dref:close() end
|
||||
|
||||
end,
|
||||
|
||||
addChildren = function()
|
||||
-- .children is a convenient
|
||||
foreach( app.cache.items, function(k,exp)
|
||||
exp.children = exp.children or {}
|
||||
if exp.parent then
|
||||
exp.parent.children = exp.parent.children or {}
|
||||
table.insert(exp.parent.children, exp.id)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
checkSideCarThumbnail = function(experience)
|
||||
local fullpath = experience.path
|
||||
local name = experience.name
|
||||
-- check for directory thumbnail sidecarfile
|
||||
local thumbExt = {"png","jpg","webp"}
|
||||
foreach( thumbExt, function(k,ext)
|
||||
local files = { fullpath .. '.' .. ext, fullpath .. '/' .. name .. '.' .. ext }
|
||||
foreach( files, function(kk,thumbnailFile)
|
||||
if util.fileExist( thumbnailFile ) then
|
||||
experience.thumbnail = "/" .. util.stripPath(thumbnailFile)
|
||||
print("✅ └─ plugin/diskscan: detected .".. ext:lower() .. " thumbnail file: " .. thumbnailFile)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,28 +55,28 @@ local plugin = {
|
|||
key='app.opts.plugin_federation_url_1',
|
||||
title='Federated URL 1',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="https://xrforge.isvery.ninja /img/xrforge.jpg",
|
||||
default="https://xrforge.isvery.ninja https://i.imgur.com/x7fzn9v.png",
|
||||
values=''
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_federation_url_2',
|
||||
title='Federated URL 2',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="https://spyduck.net /img/cover-spyduck.jpg",
|
||||
default="https://aframe.io/aframe/examples/boilerplate/hello-world/ /myverse/janusxr_tutorial/AFRAME.jpg",
|
||||
values=''
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_federation_url_3',
|
||||
title='Federated URL 3',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="https://nazrin.net/Hub /img/cover-nazrin.jpg",
|
||||
default="https://spyduck.net /img/cover-spyduck.jpg",
|
||||
values=''
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_federation_url_4',
|
||||
title='Federated URL 4',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="",
|
||||
default="https://nazrin.net/Hub /img/cover-nazrin.jpg",
|
||||
values=''
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,14 +48,6 @@ local plugin = {
|
|||
name = "Global settings",
|
||||
info = '',
|
||||
ext = {"mp3","wav","ogg","mp4","vtt","md","html","jml","jpg","png","svg"},
|
||||
layouts = {},
|
||||
getLayouts = function()
|
||||
local layouts = {}
|
||||
foreach( app.plugin.global.layout, function(k,v)
|
||||
layouts[k] = v.label
|
||||
end)
|
||||
return layouts
|
||||
end,
|
||||
opts = {
|
||||
{
|
||||
key='app.opts.admin_user',
|
||||
|
|
@ -232,7 +224,6 @@ You've got this!
|
|||
}
|
||||
},
|
||||
middleware = {
|
||||
|
||||
homepage_2D_or_3D = function(req,res,next)
|
||||
if ( (req.url == '/' or req.url == '/index.html') and app.opts.plugin_global_homepage == '3D') or (req.param.view == '3D') or (req.param.url) then
|
||||
res.template = 'page/index.html'
|
||||
|
|
@ -240,15 +231,6 @@ You've got this!
|
|||
res.template = 'page/dir.html'
|
||||
end
|
||||
next()
|
||||
end,
|
||||
|
||||
force_listing = function(req,res,next)
|
||||
if req.url:match('/dir$') then
|
||||
req.url = req.url:gsub('/dir','')
|
||||
req.param.view = '2D'
|
||||
res.template = 'page/dir.html'
|
||||
end
|
||||
next()
|
||||
end
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,17 +30,16 @@ app.on('scan_experience_file', function(exp)
|
|||
if title then
|
||||
exp.title = title:gsub("<.*","")
|
||||
end
|
||||
exp.markup = true
|
||||
exp.janusxr = exp.janusxr or {}
|
||||
exp.janusxr.wrap = nil -- erase previous 3D models
|
||||
print("✅ └─ plugin/janusxr: " .. exp.file.name)
|
||||
if data:match(pattern_aframe) and app.opts.plugin_janusxr_wrap_aframe ~= '' then
|
||||
--if not data:match("<a-sky") then
|
||||
-- exp.janusxr.room = 'room_plane'
|
||||
-- exp.janusxr.wrap = {redirect = true } -- redirect to file verbatim
|
||||
--else
|
||||
-- exp.janusxr.wrap = {file = true } -- include markup in footer
|
||||
--end
|
||||
if not data:match("<a-sky") then
|
||||
exp.janusxr.room = 'room_plane'
|
||||
exp.janusxr.wrap = {redirect = true } -- redirect to file verbatim
|
||||
else
|
||||
exp.janusxr.wrap = {file = true } -- include markup in footer
|
||||
end
|
||||
app.markViewable(exp,50)
|
||||
print("✅ └─ plugin/janusxr: AFRAME markup detected")
|
||||
else
|
||||
|
|
@ -57,18 +56,16 @@ app.on('scan_experience_file', function(exp)
|
|||
end
|
||||
|
||||
if exp.parent.redirect == nil and app.opts.plugin_janusxr_wrap_3dfile ~= "disabled"
|
||||
and not (exp.xrfragments and exp.xrfragments.qualify) then -- dont wrap xrfragments experience
|
||||
and not (exp.tag.xrfragments and exp.tag.xrfragments.qualify) then -- dont wrap xrfragments experience
|
||||
foreach( me.ext.object, function(k,ext)
|
||||
if exp.path:lower():match("."..ext.."$") then
|
||||
wrap = ext
|
||||
end
|
||||
end)
|
||||
if wrap and not (exp.janusxr and exp.janusxr.jml ~= nil) then
|
||||
-- initialize the parent
|
||||
exp.parent.janusxr = { wrap = { object = true }}
|
||||
exp.parent.janusxr.room = me.wrapRoomAroundFile( exp.parent )
|
||||
app.markViewable(exp)
|
||||
exp.parent.redirect = nil
|
||||
exp.janusxr = { wrap = { object = true }}
|
||||
exp.janusxr.room = me.wrapRoomAroundFile( exp )
|
||||
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
|
||||
app.addExperience( exp, exp.file.ino )
|
||||
print("✅ └─ plugin/janusxr: wrapping " .. exp.path)
|
||||
|
|
@ -81,26 +78,12 @@ app.on('set', function(k,v) end)
|
|||
-- this registers the plugin UI
|
||||
local rooms = { [""]="empty",empty_plane="empty (+floorcollider)",random="random room",randomurl="random room (URL-deterministic)",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||
|
||||
|
||||
-- layouts
|
||||
app.plugin.global.layout = {
|
||||
portals = {
|
||||
lib = require('plugin/janusxr/layout/portals'),
|
||||
label = 'As portals'
|
||||
},
|
||||
grid = {
|
||||
lib = require('plugin/janusxr/layout/grid'),
|
||||
label = 'As grid'
|
||||
}
|
||||
}
|
||||
|
||||
local plugin = {
|
||||
name = "JanusXR",
|
||||
info = '<a href="https://coderofsalvation.github.io/janus-guide" target="_blank">JanusXR</a> connects XR experiences via XML portals (+AFRAME (geometry)markup also supported).',
|
||||
ext = {
|
||||
object = {'glb', 'gltf', 'obj', 'fbx', 'ply', 'stl', 'wrl', 'gltf', 'glb', 'bvh' }
|
||||
},
|
||||
|
||||
opts = {
|
||||
{
|
||||
key='app.opts.plugin_janusxr_janusweb_endpoint',
|
||||
|
|
@ -206,6 +189,11 @@ local plugin = {
|
|||
}
|
||||
},
|
||||
|
||||
layout = {
|
||||
portals = require('plugin/janusxr/layout/portals'),
|
||||
grid = require('plugin/janusxr/layout/grid')
|
||||
},
|
||||
|
||||
addPortal = function(id,x,v,url,i,z,thumb,rotation,scale)
|
||||
local title = v.title
|
||||
local jml = ''
|
||||
|
|
@ -253,7 +241,7 @@ local plugin = {
|
|||
end)
|
||||
table.sort(ordered) -- ensure same order
|
||||
if url then
|
||||
room = ordered[ (me.hash_string_to_number(url) % #ordered) + 1 ]
|
||||
room = ordered[ me.hash_string_to_number(url) % #ordered ]
|
||||
else
|
||||
room = ordered[ math.random( #ordered ) ]
|
||||
end
|
||||
|
|
@ -310,15 +298,6 @@ local plugin = {
|
|||
index.color = (index.color + 1 ) % #colors
|
||||
end
|
||||
return JML
|
||||
end,
|
||||
|
||||
setLayout = function(exp, layout, opts)
|
||||
opts = opts or {}
|
||||
if not exp.janusxr then
|
||||
exp.janusxr = {}
|
||||
end
|
||||
exp.janusxr.layout = layout
|
||||
foreach( opts, function(k,v) exp.janusxr[k] = v end)
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ local portals = {
|
|||
local jml = ''
|
||||
for i,v in pairs(items) do
|
||||
local url = v.url
|
||||
--TODO
|
||||
--local width = util.pluck('parent.janusxr.portal_width', v, false) or app.opts.plugin_global_portal_width
|
||||
local width = tonumber(app.opts.plugin_global_portal_width )
|
||||
local thumb = ' shader_id="defaultportal"'
|
||||
if #v.thumbnail > 0 then
|
||||
thumb = ' thumb_id="img' .. i .. '" '
|
||||
if v.portal_width then width = tonumber(v.portal_width) end
|
||||
end
|
||||
local center = -((#items*width)/1.3) + (i*width)
|
||||
if v.dir then url = url .. "/" end
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ local plugin = {
|
|||
title='Layout assets',
|
||||
info='NOTE: use #overlay in asset-title to skip layout (sky/floor/e.g.)',
|
||||
default="grid",
|
||||
values=app.plugin.global.getLayouts()
|
||||
values={portals="As portals", grid="As grid"}
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_manyfold_layout_grid_size',
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@ local util = require('util')
|
|||
local apiSync = require('apiSync')
|
||||
|
||||
app.on('init', function()
|
||||
if not app.opts.plugin_diskscan_dir:match("^/zip/") then
|
||||
app.plugin.openbrush.api = apiSync.init( 'openbrush' )
|
||||
else
|
||||
print("[openbrush.lua] disabled..please create a 'myverse' dir we can store files into")
|
||||
end
|
||||
end)
|
||||
|
||||
local function scanTiltFile(exp)
|
||||
|
|
@ -15,43 +11,32 @@ local function scanTiltFile(exp)
|
|||
end
|
||||
end
|
||||
|
||||
local function scanForOpenBrush(exp,opts)
|
||||
local tags = app.plugin.openbrush.getTags()
|
||||
local function scanForOpenBrush(exp)
|
||||
local tags = app.plugin.openbrush.tags
|
||||
if not tags then
|
||||
tags = util.split( app.opts.plugin_openbrush_sync_hashtag, ' ')
|
||||
table.insert( tags,"openbrush")
|
||||
app.plugin.openbrush.tags = tags
|
||||
end
|
||||
foreach( tags, function(k,tag)
|
||||
tag = tag:gsub("#","")
|
||||
if exp.url:match( app.plugin.openbrush.pattern.collection(tag) ) then -- collection
|
||||
app.plugin.janusxr.setLayout( exp, app.opts.plugin_openbrush_layout, {
|
||||
room = app.opts[ "plugin_openbrush_wrap_room_" .. app.opts.plugin_openbrush_layout ] or 'empty',
|
||||
portal_width = tonumber( app.opts.plugin_openbrush_portal_width ),
|
||||
grid_size = tonumber( app.opts.plugin_openbrush_grid_size )
|
||||
})
|
||||
if exp.path:match('/' .. tag:gsub("-","%%-") .. '/') then -- might not be precise enough
|
||||
if not exp.parent.janusxr then
|
||||
exp.parent.janusxr = {}
|
||||
end
|
||||
exp.parent.janusxr.room = app.opts[ "plugin_openbrush_wrap_room_" .. app.opts.plugin_openbrush_layout ] or 'empty'
|
||||
exp.parent.portal_width = tonumber( app.opts.plugin_openbrush_portal_width )
|
||||
exp.parent.grid_size = tonumber( app.opts.plugin_openbrush_grid_size )
|
||||
exp.parent.layout = app.opts.plugin_openbrush_layout
|
||||
end
|
||||
end)
|
||||
scanTiltFile(exp)
|
||||
end
|
||||
|
||||
app.on('scan_experience', function(exp) scanForOpenBrush(exp,{dir=true}) end)
|
||||
app.on('scan_experience_janusxr', function(opts)
|
||||
local exp = opts.exp
|
||||
if exp then
|
||||
local tags = app.plugin.openbrush.getTags()
|
||||
foreach( tags, function(k,tag)
|
||||
tag = tag:gsub("#","")
|
||||
if exp.url:match( app.plugin.openbrush.pattern.assetdir(tag) ) then -- assetdir
|
||||
app.markViewable(exp)
|
||||
end
|
||||
if exp.url:match( app.plugin.openbrush.pattern.assetfile(tag) ) then -- assetfile
|
||||
-- disable janusxr room wrapping (if any)
|
||||
exp.janusxr = nil
|
||||
-- also for the parent, and redirect to indirect child asset
|
||||
if exp.parent.layout == nil and exp.parent.janusxr then
|
||||
exp.parent.janusxr = nil
|
||||
exp.parent.redirect = exp.url
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
app.on('scan_experience', scanForOpenBrush )
|
||||
app.on('scan_experience_file', scanForOpenBrush )
|
||||
app.on("scan_experience_janusxr", function(opts) scanForOpenBrush(opts.exp) end)
|
||||
|
||||
app.on('set', function(k,v)
|
||||
end)
|
||||
|
|
@ -78,7 +63,7 @@ local plugin = {
|
|||
title='Layout assets',
|
||||
info='NOTE: use #overlay in asset-title to skip layout (sky/floor/e.g.)',
|
||||
default="grid",
|
||||
values=app.plugin.global.getLayouts()
|
||||
values={portals="As portals", grid="As grid"}
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_openbrush_wrap_room_portals',
|
||||
|
|
@ -120,7 +105,7 @@ local plugin = {
|
|||
key='app.opts.plugin_openbrush_sync_folder',
|
||||
title='Sync to folder',
|
||||
info='openbrush (icosa.gallery) assets will be saved here',
|
||||
default = "./myverse/tech-demos/tronverse",
|
||||
default = "./myverse/tronverse",
|
||||
type = "dir",
|
||||
values = {} -- populated by plugin/diskscan.lua
|
||||
},
|
||||
|
|
@ -220,22 +205,6 @@ local plugin = {
|
|||
}
|
||||
},
|
||||
|
||||
pattern = {
|
||||
collection = function(tag) return '/' .. tag:gsub("-","%%-") .. '$' end,
|
||||
assetfile = function(tag) return '/' .. tag:gsub("-","%%-") .. '/' end,
|
||||
assetdir = function(tag) return '/' .. tag:gsub("-","%%-") .. '/.*[^/]$' end,
|
||||
},
|
||||
|
||||
getTags = function()
|
||||
local tags = app.plugin.openbrush.tags
|
||||
if not tags then
|
||||
tags = util.split( app.opts.plugin_openbrush_sync_hashtag, ' ')
|
||||
table.insert( tags,"openbrush")
|
||||
app.plugin.openbrush.tags = tags
|
||||
end
|
||||
return tags
|
||||
end,
|
||||
|
||||
-- expected by src/.lua/apiSync.lua
|
||||
apiCall = function(tag)
|
||||
return 'https://api.' .. app.opts.plugin_openbrush_sync_URL .. '/v1/assets?xrforge=' .. EscapeFragment(app.host)
|
||||
|
|
|
|||
|
|
@ -55,15 +55,15 @@ local plugin = {
|
|||
key='app.opts.plugin_rssatom_url_1',
|
||||
title='RSS/Atom URL 1',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="https://mastodon.online/@lvk.rss img/mastodon.jpg",
|
||||
values='https://mastodon.online/@lvk.rss img/mastodon.jpg'
|
||||
default="https://mastodon.online/@lvk.rss https://pbs.twimg.com/profile_images/1604566357206601730/dlRNo-V-_400x400.jpg",
|
||||
values='https://mastodon.online/@lvk.rss https://pbs.twimg.com/profile_images/1604566357206601730/dlRNo-V-_400x400.jpg'
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_rssatom_url_2',
|
||||
title='RSS/Atom URL 2',
|
||||
info="URL and/or Thumbnail URL (space separated)",
|
||||
default="https://nlnet.nl/feed.atom img/nlnet.jpg",
|
||||
values='https://nlnet.nl/feed.atom img/nlnet.jpg'
|
||||
default="https://nlnet.nl/feed.atom https://nlnet.nl/logo/history/logo-640x732-pre-2024.jpg",
|
||||
values='https://nlnet.nl/feed.atom https://nlnet.nl/logo/history/logo-640x732-pre-2024.jpg'
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_rssatom_url_3',
|
||||
|
|
|
|||
|
|
@ -71,40 +71,22 @@ local plugin = {
|
|||
print("[!] folder 'www' was already detected..please delete it")
|
||||
os.exit()
|
||||
end
|
||||
local selfbinary = argv[-1]
|
||||
local selfbinary = '../' .. argv[-1]
|
||||
os.execute("mkdir www www/about")
|
||||
print("cp -Lr " .. app.opts.plugin_diskscan_dir .. " " .. outdir .. "/.")
|
||||
os.execute("cp -Lr " .. app.opts.plugin_diskscan_dir .. " " .. outdir .. "/.")
|
||||
print("cd " .. outdir .. " && unzip " .. selfbinary .. " 'img/*' 'css/*' 'janusweb/*' 'shader/*'")
|
||||
os.execute("cd " .. outdir .. " && unzip " .. selfbinary .. " 'img/*' 'css/*' 'janusweb/*' 'shader/*'")
|
||||
|
||||
foreach( app.cache.items, function(k,v)
|
||||
if v.dir then
|
||||
table.insert(urls, v.url .. ".rss" )
|
||||
table.insert(urls, v.url )
|
||||
urlLast = v.url
|
||||
end
|
||||
if #v.children > 1 then
|
||||
table.insert(urls, v.url .. "/assets" )
|
||||
urlLast = v.url
|
||||
end
|
||||
end)
|
||||
|
||||
app.on('response', function(opts)
|
||||
local body = opts.res._body -- capture the output
|
||||
local url = opts.req.url:gsub("//","/")
|
||||
local dir = url:gsub("/$","")
|
||||
local isfile = url:match("%.[a-zA-Z0-9]+$")
|
||||
if isfile then
|
||||
dir = url:gsub("/[^/]+$", "")
|
||||
end
|
||||
print("mkdir -p " .. outdir .. dir )
|
||||
os.execute("mkdir -p " .. outdir .. dir)
|
||||
if isfile then
|
||||
util.writefile( outdir .. url, body )
|
||||
else
|
||||
util.writefile( outdir .. url .. '/index.html', body )
|
||||
end
|
||||
end)
|
||||
|
||||
foreach( urls, function(k,url)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ app.on('scan_experience_file', function(exp)
|
|||
local sfile = exp.path:gsub("."..ext.."$", "."..sidecarExt)
|
||||
if util.fileExist( sfile ) then
|
||||
exp.sidecarfile[ sidecarExt ] = "/" .. util.stripPath(sfile)
|
||||
exp.parent.portal3D = false
|
||||
end
|
||||
end)
|
||||
-- set thumbnail if any
|
||||
|
|
@ -39,15 +40,15 @@ app.on('scan_experience_file', function(exp)
|
|||
if util.fileExist( jsonfile ) then
|
||||
exp.sidecarfile.JSONXRF = me.detectHrefInStruct( json.decode( util.readfile(jsonfile) ) )
|
||||
end
|
||||
exp.xrfragments = {
|
||||
exp.tag.xrfragments = {
|
||||
qualify = (hasHref or exp.sidecarfile.png or exp.sidecarfile.vtt or exp.sidecarfile.ogg or exp.sidecarfile.json) and true or false,
|
||||
href = hasHref
|
||||
}
|
||||
if exp.xrfragments.qualify then
|
||||
if exp.tag.xrfragments.qualify then
|
||||
app.markViewable(exp, 100)
|
||||
print("✅ └─ plugin/xrfragments: detected xrfragments experience")
|
||||
end
|
||||
if exp.xrfragments.href then
|
||||
if exp.tag.xrfragments.href then
|
||||
exp.parent.redirect = exp.url -- mark parent to redirect to this standalone url instead
|
||||
end
|
||||
foreach(exp.sidecarfile, function(ext,v)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ local describe, it, expect = lust.describe, lust.it, lust.expect
|
|||
|
||||
lust.queueServerRequest = util.queueServerRequest
|
||||
|
||||
require('test/plugin_global')(lust)
|
||||
require('test/plugin_git')(lust)
|
||||
require('test/plugin_diskscan')(lust)
|
||||
require('test/plugin_xrfragment')(lust)
|
||||
--require('test/plugin_global')(lust)
|
||||
--require('test/plugin_git')(lust)
|
||||
--require('test/plugin_diskscan')(lust)
|
||||
--require('test/plugin_xrfragment')(lust)
|
||||
require('test/plugin_janusxr')(lust)
|
||||
require('test/plugin_openbrush')(lust)
|
||||
require('test/util')(lust)
|
||||
--require('test/plugin_openbrush')(lust)
|
||||
--require('test/util')(lust)
|
||||
|
||||
if lust.errors == 0 then
|
||||
print("✅ all tests passed")
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ return function(lust)
|
|||
app.init()
|
||||
local destdir = app.opts.plugin_diskscan_dir .. '/' .. 'xrfragment'
|
||||
expect( util.fileExist( destdir ) ).to.be.truthy()
|
||||
os.execute('rm -rf ' .. destdir)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -7,48 +7,13 @@ return function(lust)
|
|||
|
||||
describe('ℹ️ wrap 3D file', function() -- Can be nested
|
||||
it('detect & serve to iframe', function()
|
||||
app.init()
|
||||
app.use( require('page/dir').middleware )
|
||||
app.use( app.response() )
|
||||
app.on('response', function(opts)
|
||||
expect( not opts.res._body:match('use_local_asset=""') ).to.be.truthy()
|
||||
end)
|
||||
|
||||
local url = '/myverse/murials/murial2D'
|
||||
|
||||
foreach(app.cache.items, function(k,exp)
|
||||
if exp.url:match(url) then
|
||||
if exp.url:match( url .. "$") then
|
||||
--print_r(exp)
|
||||
lust.queueServerRequest('GET', url, nil, nil, nil, nil, nil, 8080 )
|
||||
app.run()
|
||||
end
|
||||
end
|
||||
end)
|
||||
-- *TODO*
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('ℹ️ wrap AFRAME file', function() -- Can be nested
|
||||
it('detect & serve to iframe', function()
|
||||
app.init()
|
||||
app.use( require('page/dir').middleware )
|
||||
app.use( app.response() )
|
||||
app.on('response', function(opts)
|
||||
expect( not opts.res._body:match('use_local_asset=""') ).to.be.truthy()
|
||||
expect( not opts.res._body:match('<object id="/myverse/janusxr_tutorial/AFRAME/index.html"/>') ).to.be.truthy()
|
||||
end)
|
||||
|
||||
local url = '/myverse/janusxr_tutorial/AFRAME'
|
||||
|
||||
foreach(app.cache.items, function(k,exp)
|
||||
if exp.url:match(url) then
|
||||
if exp.url:match( url .. "$") then
|
||||
--print_r(exp)
|
||||
lust.queueServerRequest('GET', url, nil, nil, nil, nil, nil, 8080 )
|
||||
app.run()
|
||||
end
|
||||
end
|
||||
end)
|
||||
-- *TODO*
|
||||
end)
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,29 +17,6 @@ return function(lust)
|
|||
expect( t.assets and #t.assets > 0 ).to.be.truthy()
|
||||
end)
|
||||
|
||||
describe('ℹ️ grid-layout', function() -- Can be nested
|
||||
it('unwrap janusxr-room for assets', function()
|
||||
app.init()
|
||||
app.use( require('page/dir').middleware )
|
||||
app.use( app.response() )
|
||||
app.on('response', function(opts)
|
||||
expect( not opts.res._body:match('/myverse/tronverse/tronverse-icosagallery/_0dycp4HDxf4-tronverse_floor-overlay-tronverse-icosagallery/tronverse_floor.glb') ).to.be.truthy()
|
||||
end)
|
||||
|
||||
local url = '/myverse/tronverse/tronverse-icosagallery'
|
||||
|
||||
foreach(app.cache.items, function(k,exp)
|
||||
if exp.url:match(url) then
|
||||
if exp.url:match( url .. "$") then
|
||||
--print_r(exp)
|
||||
lust.queueServerRequest('GET', url, nil, nil, nil, nil, nil, 8080 )
|
||||
app.run()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
--describe('download icosa.gallery assets', function() -- Can be nested
|
||||
-- local json = util.readfile('/zip/test/json/icosagallery.json')
|
||||
-- local opts = {body=json}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ OUTDIR=result/bin
|
|||
REDBEAN_URL="https://redbean.dev/redbean-3.0.0.com"
|
||||
REDBEAN_CRC="382f1288bb96ace4bab5145e7df236846c33cc4f1be69233710682a9e71e7467 $OUTDIR/xrforge.com"
|
||||
|
||||
get(){
|
||||
download(){
|
||||
|
||||
redbean(){
|
||||
test -d $OUTDIR || mkdir -p $OUTDIR
|
||||
|
|
@ -32,34 +32,26 @@ get(){
|
|||
|
||||
janusweb(){
|
||||
set -x
|
||||
test -d pkg/janusweb || {
|
||||
mkdir pkg &>/dev/null || true
|
||||
test -d janusweb || {
|
||||
version=1.7.5
|
||||
test -f janusweb-${version}.tar.gz || {
|
||||
wget "https://github.com/coderofsalvation/janusweb/releases/download/v${version}-rc/janusweb-${version}.tar.gz"
|
||||
}
|
||||
test -d janusweb-${version} || tar -xvf janusweb-${version}.tar.gz
|
||||
mv janusweb-${version} pkg/janusweb
|
||||
mv janusweb-${version} janusweb
|
||||
}
|
||||
set -x
|
||||
rsync -avLu pkg/janusweb src/. # overlay but leave newer files intact
|
||||
# cleanup
|
||||
rm src/janusweb/janusxr.com || true
|
||||
rm src/janusweb/test || true
|
||||
rm src/janusweb/media/test || true
|
||||
# set xrforge as defualt config
|
||||
cp src/janusweb/media/assets/webui/{xrforge,default}.json
|
||||
test -d src/janusweb || cp -Lr janusweb src/janusweb
|
||||
}
|
||||
|
||||
"$@"
|
||||
}
|
||||
|
||||
build(){
|
||||
get redbean
|
||||
get janusweb
|
||||
download redbean
|
||||
download janusweb
|
||||
cd src
|
||||
bundle(){ zip -yr $1 * .lua .init.lua .args; }
|
||||
bundle ../result/bin/xrforge.com
|
||||
unzip -l ../result/bin/xrforge.com
|
||||
test -n "$ARCH" && bundle ../result/bin/xrforge-$ARCH.com
|
||||
}
|
||||
|
||||
|
|
|
|||