update rook hooks & templates
This commit is contained in:
parent
258df4621f
commit
677dab8abd
15 changed files with 402 additions and 0 deletions
92
manyfold/root/.config/janus-server/config.js
Normal file
92
manyfold/root/.config/janus-server/config.js
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/* Socket port to listen on */
|
||||||
|
port: 5566,
|
||||||
|
|
||||||
|
/* SSL configurations */
|
||||||
|
|
||||||
|
/*
|
||||||
|
************************************************************************
|
||||||
|
*** The following options REQUIRE a redis database to function ! ***
|
||||||
|
************************************************************************
|
||||||
|
*/
|
||||||
|
multiprocess: {
|
||||||
|
enabled: false, // requires redis for IPC
|
||||||
|
processes: 1
|
||||||
|
},
|
||||||
|
partyList: false,
|
||||||
|
redis: {
|
||||||
|
host: "127.0.0.1",
|
||||||
|
port: 6379,
|
||||||
|
//password: null
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
************************************************************************
|
||||||
|
*** The following options REQUIRE a MySQL database to function ! ***
|
||||||
|
************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//// If you want to track how many users are online, set UserList: true.
|
||||||
|
//Userlist: false,
|
||||||
|
|
||||||
|
///* Controls how many results a request for 'users_online' receives. */
|
||||||
|
//maxUserResults: 100,
|
||||||
|
|
||||||
|
///* MySQL database connection info for janus-mysql-auth and janus-mysql-userlist */
|
||||||
|
//MySQL_Hostname: 'localhost',
|
||||||
|
//MySQL_Database: 'janusvr',
|
||||||
|
//MySQL_Username: 'janusvr',
|
||||||
|
//MySQL_Password: 'janusvr',
|
||||||
|
|
||||||
|
///* Authentication mode:
|
||||||
|
// 'none' - Will not attempt to authenticate users,
|
||||||
|
// anyone can connect with any unused userId.
|
||||||
|
// 'optional' - Anyone can connect, but if userId has been registered
|
||||||
|
// a password must be provided.
|
||||||
|
// 'required' - Only users with userids and passwords are allowed to connect.
|
||||||
|
//*/
|
||||||
|
//authMode: "none",
|
||||||
|
//
|
||||||
|
//popularRooms: {
|
||||||
|
// halfLife: 7 * 24 * 60 * 60 * 1000, // set halflife to 7 days
|
||||||
|
// updateInterval: 3000, // interval between weight updates on the popular rooms
|
||||||
|
// masterToken: "changethis"
|
||||||
|
//},
|
||||||
|
|
||||||
|
/*
|
||||||
|
************************************************************************
|
||||||
|
*** The previous options REQUIRE a MySQL database to function ! ***
|
||||||
|
************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Plugins must be installed from npm, or manually created in node_module/ to be loaded. */
|
||||||
|
/* hookPlugins are called while parsing messages */
|
||||||
|
hookPlugins: {
|
||||||
|
logon: {
|
||||||
|
plugins: [
|
||||||
|
//" janus-mysql-auth"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
enter_room: {
|
||||||
|
plugins: [
|
||||||
|
// "janus-mysql-popular"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/* methodPlugins add new commands to the server */
|
||||||
|
methodPlugins: {
|
||||||
|
// ping: { plugin: "janus-method-ping" }
|
||||||
|
},
|
||||||
|
|
||||||
|
/* intervalPlugins are called in intervals specified in seconds. */
|
||||||
|
intervalPlugins: [
|
||||||
|
//{ plugin: "janus-mysql-userlist-official", interval: 6 }
|
||||||
|
],
|
||||||
|
};
|
||||||
76
manyfold/root/bin/random_thumbnail.sh
Executable file
76
manyfold/root/bin/random_thumbnail.sh
Executable file
|
|
@ -0,0 +1,76 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test -n "$2" || { echo "Usage: $0 <input.jpg> <output.jpg> [blurtimes]"; exit 0; }
|
||||||
|
|
||||||
|
# --- Configuration ---
|
||||||
|
# Define the size of the rectangle to crop (Width x Height)
|
||||||
|
CROP_SIZE="128x128"
|
||||||
|
CROP_WIDTH=128
|
||||||
|
CROP_HEIGHT=128
|
||||||
|
BLURTIMES=0
|
||||||
|
|
||||||
|
test -n "$3" && BLURTIMES=$3
|
||||||
|
|
||||||
|
# Input and Output filenames
|
||||||
|
INPUT_FILE="$1" # <-- **CHANGE THIS** to your actual input file name
|
||||||
|
OUTPUT_FILE="$2"
|
||||||
|
|
||||||
|
# --- Pre-Check: Ensure the input file exists ---
|
||||||
|
if [ ! -f "$INPUT_FILE" ]; then
|
||||||
|
echo "🚨 Error: Input file '$INPUT_FILE' not found."
|
||||||
|
echo "Please update the INPUT_FILE variable in the script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 1. Get the dimensions of the input image ---
|
||||||
|
# The 'identify' command returns image info; we use awk/cut to extract just the dimensions.
|
||||||
|
# Example output format: "1920x1080"
|
||||||
|
IMAGE_GEOMETRY=$(identify -format "%wx%h" "$INPUT_FILE")
|
||||||
|
IMAGE_WIDTH=$(echo "$IMAGE_GEOMETRY" | cut -dx -f1)
|
||||||
|
IMAGE_HEIGHT=$(echo "$IMAGE_GEOMETRY" | cut -dx -f2)
|
||||||
|
|
||||||
|
echo "Input Image: $INPUT_FILE (${IMAGE_GEOMETRY})"
|
||||||
|
echo "Crop Area: $CROP_SIZE"
|
||||||
|
|
||||||
|
# --- 2. Calculate the maximum possible starting coordinates ---
|
||||||
|
# To ensure the 16x16 crop doesn't go off the edge:
|
||||||
|
# Max_X_Start = Image_Width - Crop_Width
|
||||||
|
# Max_Y_Start = Image_Height - Crop_Height
|
||||||
|
MAX_X=$((IMAGE_WIDTH - CROP_WIDTH))
|
||||||
|
MAX_Y=$((IMAGE_HEIGHT - CROP_HEIGHT))
|
||||||
|
|
||||||
|
# Check if the image is too small to crop
|
||||||
|
if [ $MAX_X -lt 0 ] || [ $MAX_Y -lt 0 ]; then
|
||||||
|
echo "🚨 Error: Image dimensions ($IMAGE_GEOMETRY) are smaller than the crop size ($CROP_SIZE)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 3. Generate Random Coordinates ---
|
||||||
|
# $RANDOM generates a pseudo-random integer (0 to 32767).
|
||||||
|
# We use the modulo operator (%) to limit it to the required range (0 to MAX_X or MAX_Y).
|
||||||
|
|
||||||
|
# Random X-coordinate (0 to MAX_X)
|
||||||
|
RANDOM_X=$((RANDOM % (MAX_X + 1)))
|
||||||
|
|
||||||
|
# Random Y-coordinate (0 to MAX_Y)
|
||||||
|
RANDOM_Y=$((RANDOM % (MAX_Y + 1)))
|
||||||
|
|
||||||
|
# --- 4. Assemble the ImageMagick Geometry String ---
|
||||||
|
# The final geometry string is: <Width>x<Height>+<X_Offset>+<Y_Offset>
|
||||||
|
CROP_GEOMETRY="${CROP_SIZE}+${RANDOM_X}+${RANDOM_Y}"
|
||||||
|
|
||||||
|
echo "Random Start Coordinate: X=${RANDOM_X}, Y=${RANDOM_Y}"
|
||||||
|
echo "ImageMagick Crop String: ${CROP_GEOMETRY}"
|
||||||
|
|
||||||
|
# --- 5. Execute the ImageMagick Command ---
|
||||||
|
# 'convert' is the core command.
|
||||||
|
# -crop: Specifies the geometry string for cropping.
|
||||||
|
# -quality 100: (Optional) Ensures best quality for the output JPEG.
|
||||||
|
test -f $OUTPUT_FILE && rm $OUTPUT_FILE
|
||||||
|
magick "$INPUT_FILE" \
|
||||||
|
-crop "$CROP_GEOMETRY" \
|
||||||
|
-blur 0x$BLURTIMES \
|
||||||
|
-quality 100 \
|
||||||
|
"$OUTPUT_FILE"
|
||||||
|
|
||||||
|
echo "✅ thumbnail generated"
|
||||||
116
manyfold/root/hook.d/boot/import_instances.rb
Executable file
116
manyfold/root/hook.d/boot/import_instances.rb
Executable file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
require 'yaml' # For reading input
|
||||||
|
require 'json' # <--- REQUIRED FOR OUTPUT
|
||||||
|
require 'fileutils'
|
||||||
|
require 'pathname'
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
require 'erb'
|
||||||
|
|
||||||
|
if ! ENV['IMPORT_INSTANCES']
|
||||||
|
exit 0 # nothing to do
|
||||||
|
end
|
||||||
|
|
||||||
|
INPUT_ROOT_DIR = '/root/instances'
|
||||||
|
OUTPUT_ROOT_DIR = '/mnt/instances'
|
||||||
|
|
||||||
|
FileUtils.mkdir_p(OUTPUT_ROOT_DIR)
|
||||||
|
|
||||||
|
puts "scanning yaml-files in /root/instances"
|
||||||
|
|
||||||
|
# 2. Iterate over all 'room.yaml' files recursively
|
||||||
|
Dir.glob(File.join(INPUT_ROOT_DIR, '**', 'room.yaml')).each do |input_file_path|
|
||||||
|
|
||||||
|
begin
|
||||||
|
input_data = YAML.load_file(input_file_path)
|
||||||
|
rescue StandardError => e
|
||||||
|
puts " ❌ Error reading or parsing YAML: #{e.message}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
relative_path = Pathname.new(input_file_path).relative_path_from(Pathname.new(INPUT_ROOT_DIR))
|
||||||
|
path_components = relative_path.to_s.split(File::SEPARATOR)
|
||||||
|
|
||||||
|
unless path_components.length >= 4
|
||||||
|
puts " ⚠️ Skipping: Path structure too shallow. Expected SERVER/AUTHOR/ROOM_NAME/room.yaml"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
server_name = path_components[0]
|
||||||
|
author_name = path_components[1]
|
||||||
|
room_name = path_components[2]
|
||||||
|
|
||||||
|
begin
|
||||||
|
u = input_data['url']
|
||||||
|
r = Net::HTTP.new(URI.parse(u).host, URI.parse(u).port)
|
||||||
|
r.use_ssl = (URI.parse(u).scheme == 'https')
|
||||||
|
|
||||||
|
a = r.request(Net::HTTP::Head.new(URI.parse(u).request_uri))
|
||||||
|
|
||||||
|
if a.code.to_i != 200
|
||||||
|
puts " ⚠️ Skipping:HTTP code #{a.code} received :/"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# 5. Construct the final data structure (Hash)
|
||||||
|
output_data = {}
|
||||||
|
output_data['homepage'] = input_data['url']
|
||||||
|
output_data['name'] = input_data['title']
|
||||||
|
output_data['description'] = input_data['description']
|
||||||
|
output_data['image'] = input_data['thumbnail']
|
||||||
|
output_data['tags'] = [server_name]
|
||||||
|
|
||||||
|
output_dir = File.join(OUTPUT_ROOT_DIR, author_name, room_name)
|
||||||
|
output_file_path = File.join(output_dir, 'datapackage.json')
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
url = URI(input_data['thumbnail'])
|
||||||
|
output_path = output_dir+"/.xrforge/thumbnail.jpg"
|
||||||
|
|
||||||
|
Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == "https") do |http|
|
||||||
|
request = Net::HTTP::Get.new(url)
|
||||||
|
http.request(request) do |response|
|
||||||
|
raise "Download failed: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
|
||||||
|
|
||||||
|
File.open(output_path, "wb") do |file|
|
||||||
|
response.read_body do |chunk|
|
||||||
|
file.write(chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if a.code.to_i != 200
|
||||||
|
puts " ⚠️ Skipping:HTTP code #{a.code} receivedfor thumbnail :/"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# write datapackage.json
|
||||||
|
FileUtils.mkdir_p(output_dir) # Create directory (including parents)
|
||||||
|
File.write(output_file_path, JSON.pretty_generate(output_data))
|
||||||
|
puts " ✅ HTTP 200: Wrote #{output_file_path}"
|
||||||
|
|
||||||
|
# write janusxr.html + scene.jml
|
||||||
|
templateDir = File.dirname(__FILE__)+"/../../templates/"
|
||||||
|
FileUtils.mkdir_p(output_dir+"/.xrforge") # Create directory (including parents)
|
||||||
|
data = output_data
|
||||||
|
data['title'] = output_data['name']
|
||||||
|
$links = []
|
||||||
|
janusweb_src = ENV['DEV'] ? "/mnt/janusweb/janusweb.js" : "/mnt/janusweb/janusweb.min.js"
|
||||||
|
jml = ERB.new( File.read( templateDir+"JML/portalAR.erb" ) ).result(binding)
|
||||||
|
html = ERB.new( File.read( templateDir+"JML/client.html") ).result(binding)
|
||||||
|
File.write(output_dir+"/.xrforge/scene.jml", jml )
|
||||||
|
puts " ✅ Wrote #{output_dir}/.xrforge/scene.jml"
|
||||||
|
File.write(output_dir+"/.xrforge/janusxr.html", html )
|
||||||
|
puts " ✅ Wrote #{output_dir}/.xrforge/janusxr.html"
|
||||||
|
|
||||||
|
rescue StandardError => e
|
||||||
|
puts " ❌ Error writing output file: #{e.message}"
|
||||||
|
end
|
||||||
|
rescue StandardError => e
|
||||||
|
# Optionally handle error quietly or output e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
url: https://vesta.janusxr.org/spyduck/lains-bedroom-serial-experiments-lain
|
||||||
|
title: "Lain's Bedroom"
|
||||||
|
description: "Recreation of the protagonist's bedroom from Serial Experiments Lain"
|
||||||
|
thumbnail: https://vesta.janusxr.org/assets/thumbs/spyduck/c59d083f4c3e9fcde3f525d28d8acd69.jpg
|
||||||
62
manyfold/root/templates/JML/client.html
Normal file
62
manyfold/root/templates/JML/client.html
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%=data['title']%> - JanusXR</title>
|
||||||
|
|
||||||
|
<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 http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-12" content="Avy/Fo2QM5trR+WVHnaVz0t3LVltGxx3yvpSYSCC2oklwuDEYUEK6YdnxYv4p687MJGB61q//htZUvSIZPg93goAAABOeyJvcmlnaW4iOiJodHRwczovL3dlYi5qYW51c3ZyLmNvbTo0NDMiLCJmZWF0dXJlIjoiV2ViVlIiLCJleHBpcnkiOjE0OTczMTIwMDB9">
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:site" content="@bai0" />
|
||||||
|
<meta name="twitter:title" content="JanusWeb" />
|
||||||
|
<meta name="twitter:description" content="The World Within The Web" />
|
||||||
|
<meta name="twitter:image" content="https://janusxr.org/backgrounds/wallpapers/generic.png" />
|
||||||
|
<meta name="twitter:image:alt" content="JanusWeb" />
|
||||||
|
<meta property="og:app_id" content="1197654320349894" />
|
||||||
|
<meta property="og:url" content="https://web.janusxr.org/" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:title" content="JanusWeb" />
|
||||||
|
<meta property="og:description" content="The World Within The Web" />
|
||||||
|
<meta property="og:image" content="https://janusxr.com/backgrounds/wallpapers/generic.png" />
|
||||||
|
-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<janus-viewer homepage="/" autostart="false" showavatar="false">
|
||||||
|
<%=jml%>
|
||||||
|
</janus-viewer>
|
||||||
|
<!-- archive.org hints -->
|
||||||
|
<% $links.each do |link| %>
|
||||||
|
<a href="<%=link%>"></a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- map URL query args to room-attributes -->
|
||||||
|
<script>
|
||||||
|
args = new URLSearchParams(document.location.search)
|
||||||
|
for( const [k,v] of args.entries()) document.querySelector("Room").setAttribute(k,v)
|
||||||
|
</script>
|
||||||
|
<script src="<%=janusweb_src%>"></script>
|
||||||
|
<script>
|
||||||
|
let serveruri = "ws://"+document.location.hostname+":5566"
|
||||||
|
let corsproxy = document.location.origin.replace(/:[0-9].*/,'')+":5577/"
|
||||||
|
if( document.location.protocol.match(/https/) ){
|
||||||
|
corsproxy = corsproxy.replace(/\/\//,"//cors.").replace(/:[0-9].*/,"/")
|
||||||
|
serveruri = serveruri.replace(/ws:\/\//,"wss://presence.").replace(/:[0-9].*/,"")
|
||||||
|
}
|
||||||
|
elation.config.set("engine.assets.corsproxy", corsproxy )
|
||||||
|
elation.config.set("janusweb.network.host", serveruri )
|
||||||
|
elation.janusweb.init({
|
||||||
|
uiconfig: `/janusweb/media/assets/webui/${ args.get("networking") == "false" ? "preview" : "default"}.json`,
|
||||||
|
// for more opts see getClientArgs() in
|
||||||
|
// https://github.com/jbaicoianu/janusweb/blob/master/scripts/client.js
|
||||||
|
})
|
||||||
|
.then( (client) => {
|
||||||
|
elation.janusweb.init = function(){} // prevent multi-inits
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
manyfold/root/templates/JML/header.erb
Normal file
9
manyfold/root/templates/JML/header.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!-- Hi there! Below is autogenerated JanusXR Markup (JML). -->
|
||||||
|
<!-- If you want to tweak it, then first disable autogeneration -->
|
||||||
|
<!-- How? remove the 'autogenerate' attribute from the <Room> tag below -->
|
||||||
|
<!-- Please note: the tags will **no longer** reflect this JML -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- JML info: -->
|
||||||
|
<!-- https://coderofsalvation.github.io/janus-guide/#/examples/markup -->
|
||||||
|
<!-- https://janusxr.org/docs/build/introtojml/index.html -->
|
||||||
|
|
||||||
8
manyfold/root/templates/JML/portalAR.erb
Normal file
8
manyfold/root/templates/JML/portalAR.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<fireboxroom>
|
||||||
|
<Assets>
|
||||||
|
</Assets>
|
||||||
|
<Room pos="0 0 0" skybox="true" showavatar="false" use_local_asset="room_plane">
|
||||||
|
<link url="<%=data['url']%> col="1.0 0.0 1.0" title="<%=data['title']%> pos="0 0 5" scale="1.8 3.2 1"/>
|
||||||
|
<Paragraph pos="2.8 1 -3.21" fwd="0 0 1" lighting="false" rotation="180 -45 180" col="0.5 0.8 0.5" scale="2 2 2" font_size="50" locked="false"><%=data['description']%></Paragraph>
|
||||||
|
</Room>
|
||||||
|
</fireboxroom>
|
||||||
10
manyfold/root/templates/JML/room.erb
Normal file
10
manyfold/root/templates/JML/room.erb
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<FireBoxRoom>
|
||||||
|
<Assets>
|
||||||
|
<%=assets%>
|
||||||
|
<assetimage id="home" src="/view/home.png"/>
|
||||||
|
</Assets>
|
||||||
|
<Room autogenerate="true" <%=use_local_asset%> <%=private%> <%=showavatar%> <%=startpos%>>
|
||||||
|
<%=objects%>
|
||||||
|
<link url="/models" col="1.0 0.0 1.0" title="back to home" pos="0 0 -5" scale="1.8 3.2 1" image_id="home"/>
|
||||||
|
</Room>
|
||||||
|
</FireBoxRoom>
|
||||||
10
manyfold/root/templates/JML/room.xrforge.erb
Normal file
10
manyfold/root/templates/JML/room.xrforge.erb
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<FireBoxRoom>
|
||||||
|
<Assets>
|
||||||
|
<%=assets%>
|
||||||
|
<assetimage id="home" src="/view/home.png"/>
|
||||||
|
</Assets>
|
||||||
|
<Room autogenerate="true" <%=use_local_asset%> <%=private%> <%=showavatar%> <%=startpos%>>
|
||||||
|
<%=objects%>
|
||||||
|
<link url="/models" col="1.0 0.0 1.0" title="back to home" pos="0 0 -5" scale="1.8 3.2 1" image_id="home"/>
|
||||||
|
</Room>
|
||||||
|
</FireBoxRoom>
|
||||||
15
manyfold/root/templates/audiovisual/audiovisual.xml
Normal file
15
manyfold/root/templates/audiovisual/audiovisual.xml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<fireboxroom>
|
||||||
|
<assets>
|
||||||
|
<assetimage id="image" src="lobby.png"/>
|
||||||
|
<assetvideo auto_play="true" id="video" loop="true" src="video.mp4"/>
|
||||||
|
<assetobject id="rplane" src="roundedplane.glb"/>
|
||||||
|
</assets>
|
||||||
|
<room use_local_asset="room5" pos="0 0 -10">
|
||||||
|
<Object cull_face="none" id="rplane" js_id="video" lighting="false" pos="0 6.5 5.5" scale="4 4 1" video_id="video"/>
|
||||||
|
<Object cull_face="none" id="rplane" js_id="text_rplane" lighting="false" pos="2.69 1.84 -3.37" rotation="0 45 0" scale="1.6 1 1"/>
|
||||||
|
<Paragraph pos="2.8 1 -3.21" fwd="0 0 1" lighting="false" rotation="180 -45 180" col="0.5 0.8 0.5" scale="2 2 2" font_size="50" locked="false">
|
||||||
|
This is a template for audiovisual experiences. Use it for beautiful spatial music/video releases, by just upload/replacing an audio- or video-file.
|
||||||
|
</Paragraph>
|
||||||
|
</room>
|
||||||
|
</fireboxroom>
|
||||||
|
<title>Audiovisual</title>
|
||||||
BIN
manyfold/root/templates/audiovisual/lobby.png
Normal file
BIN
manyfold/root/templates/audiovisual/lobby.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 821 KiB |
BIN
manyfold/root/templates/audiovisual/roundedplane.glb
Normal file
BIN
manyfold/root/templates/audiovisual/roundedplane.glb
Normal file
Binary file not shown.
BIN
manyfold/root/templates/audiovisual/video.mp4
Normal file
BIN
manyfold/root/templates/audiovisual/video.mp4
Normal file
Binary file not shown.
BIN
manyfold/root/templates/audiovisual/video.webm
Normal file
BIN
manyfold/root/templates/audiovisual/video.webm
Normal file
Binary file not shown.
BIN
manyfold/root/templates/thumbnailseed.jpg
Normal file
BIN
manyfold/root/templates/thumbnailseed.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Loading…
Add table
Reference in a new issue