Compare commits
3 Commits
168c725650
...
structure-
| Author | SHA1 | Date | |
|---|---|---|---|
| 2df5a71241 | |||
| 32424e7b0b | |||
| 9c29894241 |
BIN
assets/pano/gradient.jpg
Normal file
BIN
assets/pano/gradient.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
210
config.js
210
config.js
@@ -14,19 +14,13 @@ const theater2Popup = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
const audioBtn1 = `
|
||||
<button type="button" class="text-left btn aton-btn fs-6 mx-2" data-bs-toggle="modal" data-bs-target="#audio1">
|
||||
<i class="bi bi-play-btn me-2"></i> Esempio audio (<em>Che fiero costume</em>)
|
||||
</button>
|
||||
`;
|
||||
|
||||
export const config = {
|
||||
scene : {
|
||||
initialExposure: 0.7,
|
||||
autoLP: true,
|
||||
autoLP: false,
|
||||
},
|
||||
menu : {
|
||||
audioBtn1
|
||||
//audioBtn1
|
||||
},
|
||||
markers : [
|
||||
{
|
||||
@@ -35,7 +29,13 @@ export const config = {
|
||||
uri : `${BASE_URI}/scenes/salvador/`,
|
||||
popup: theater1Popup,
|
||||
coords: [45.4363, 12.3352],
|
||||
model: "teatro_san_salvador_20250926.gltf",
|
||||
nodes: [
|
||||
{
|
||||
label: 'Teatro',
|
||||
model: "teatro_san_salvador_20250926.gltf",
|
||||
isMain: true,
|
||||
},
|
||||
],
|
||||
pano: `pano/defsky-grass.jpg`,
|
||||
},
|
||||
{
|
||||
@@ -44,89 +44,115 @@ export const config = {
|
||||
uri : `${BASE_URI}/scenes/ssgp/`,
|
||||
popup: theater2Popup,
|
||||
coords: [45.4401, 12.3408],
|
||||
nodes: [
|
||||
/*
|
||||
{
|
||||
label: 'Struttura principale',
|
||||
model: 'models/ssgp/Teatro_SSGP_Full_ConSottrazioni.glb',
|
||||
isMain: true,
|
||||
},
|
||||
*/
|
||||
{
|
||||
label: 'Struttura parete di fondo',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_Struttura_parete_di_fondo.glb',
|
||||
isMain: true,
|
||||
},
|
||||
{
|
||||
label: 'Ballatoio',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ballatoio.glb',
|
||||
},
|
||||
{
|
||||
label: 'Boccascena',
|
||||
model: 'models/ssgp/Teatro_SSGP_Boccascena.glb',
|
||||
},
|
||||
{
|
||||
label: 'Fossa orchestra',
|
||||
model: 'models/ssgp/Teatro_SSGP_Fossa_orchestra.glb',
|
||||
},
|
||||
{
|
||||
label: 'Graticcia',
|
||||
model: 'models/ssgp/Teatro_SSGP_Graticcia.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 1',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine1.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 2',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine2.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 3',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine3.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 4',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine4.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 5',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine5.glb',
|
||||
},
|
||||
{
|
||||
label: 'Palcoscenico',
|
||||
model: 'models/ssgp/Teatro_SSGP_Palcoscenico.glb',
|
||||
},
|
||||
{
|
||||
label: 'Parapetto scala piani',
|
||||
model: 'models/ssgp/Teatro_SSGP_parapetto_scala_piani.glb',
|
||||
},
|
||||
{
|
||||
label: 'Percorsi scale corridoi',
|
||||
model: 'models/ssgp/Teatro_SSGP_Percorsi_scale_corridoi.glb',
|
||||
},
|
||||
{
|
||||
label: 'Platea peplano',
|
||||
model: 'models/ssgp/Teatro_SSGP_Platea_peplano.glb',
|
||||
},
|
||||
{
|
||||
label: 'Quinte architettoniche fisse',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_quinte_architettoniche_fisse.glb',
|
||||
},
|
||||
{
|
||||
label: 'Quinte architettoniche mobili',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_quinte_architettoniche_mobili.glb',
|
||||
},
|
||||
{
|
||||
label: 'Spazio tecnico superiore',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_Spazio_tecnico_sup_soffitta.glb',
|
||||
},
|
||||
{
|
||||
label: 'Spazio tecnico inferiore',
|
||||
model: 'models/ssgp/Teatro_SSGP_Spazio_tecnico_inf.glb',
|
||||
},
|
||||
],
|
||||
pano: `pano/defsky-grass.jpg`,
|
||||
nodes: {
|
||||
groups: [
|
||||
{
|
||||
label: 'Teatro',
|
||||
layers: [
|
||||
{
|
||||
label: 'Struttura complessiva',
|
||||
model: 'models/ssgp/Teatro_SSGP_Full_ConSottrazioni.glb',
|
||||
//isMain: true,
|
||||
},
|
||||
{
|
||||
label: 'Involucro',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_Struttura_parete_di_fondo.glb',
|
||||
isMain: true,
|
||||
opacity: 0.2,
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Sala / Auditorium',
|
||||
layers: [
|
||||
{
|
||||
label: 'Peplano / Platea',
|
||||
model: 'models/ssgp/Teatro_SSGP_Platea_peplano.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 1',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine1.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 2',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine2.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 3',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine3.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 4',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine4.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ordine 5',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ordine5.glb',
|
||||
},
|
||||
{
|
||||
label: 'Parapetto',
|
||||
model: 'models/ssgp/Teatro_SSGP_parapetto_scala_piani.glb',
|
||||
},
|
||||
{
|
||||
label: 'Percorsi pubblico',
|
||||
model: 'models/ssgp/Teatro_SSGP_Percorsi_scale_corridoi.glb',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Scena',
|
||||
layers: [
|
||||
{
|
||||
label: 'Palcoscenico',
|
||||
model: 'models/ssgp/Teatro_SSGP_Palcoscenico.glb',
|
||||
},
|
||||
{
|
||||
label: 'Boccascena / Proscenio',
|
||||
model: 'models/ssgp/Teatro_SSGP_Boccascena.glb',
|
||||
},
|
||||
{
|
||||
label: 'Quinte architettoniche fisse',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_quinte_architettoniche_fisse.glb',
|
||||
},
|
||||
{
|
||||
label: 'Quinte architettoniche mobili',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_quinte_architettoniche_mobili.glb',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Spazi tecnici',
|
||||
layers: [
|
||||
{
|
||||
label: 'Spazio tecnico superiore',
|
||||
model: 'models/ssgp/Teatro_SSGP_Layer_Spazio_tecnico_sup_soffitta.glb',
|
||||
},
|
||||
{
|
||||
label: 'Graticcia',
|
||||
model: 'models/ssgp/Teatro_SSGP_Graticcia.glb',
|
||||
},
|
||||
{
|
||||
label: 'Ballatoio',
|
||||
model: 'models/ssgp/Teatro_SSGP_Ballatoio.glb',
|
||||
},
|
||||
{
|
||||
label: 'Spazio tecnico inferiore',
|
||||
model: 'models/ssgp/Teatro_SSGP_Spazio_tecnico_inf.glb',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Orchestra',
|
||||
layers: [
|
||||
{
|
||||
label: 'Fossa orchestra',
|
||||
model: 'models/ssgp/Teatro_SSGP_Fossa_orchestra.glb',
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
pano: `pano/gradient.jpg`,
|
||||
}
|
||||
],
|
||||
map : {
|
||||
|
||||
@@ -62,7 +62,7 @@ Scene.createClippingPlaneMesh = function (boundingSphere) {
|
||||
const planeSize = boundingSphere.radius * 1.5;
|
||||
const mesh = new THREE.Mesh(
|
||||
new THREE.PlaneGeometry(planeSize, planeSize),
|
||||
new THREE.MeshBasicMaterial({ color: 0xffff00, opacity: 0.1, side: THREE.DoubleSide, transparent: true })
|
||||
new THREE.MeshBasicMaterial({ color: 0xffff00, opacity: 0.05, side: THREE.DoubleSide, transparent: true })
|
||||
);
|
||||
|
||||
return mesh;
|
||||
@@ -261,6 +261,12 @@ Scene.loadNodes = function (nodes) {
|
||||
let node = ATON.createSceneNode(n.label);
|
||||
node.load(n.model);
|
||||
node.setRotation(0, 1.5, 0);
|
||||
|
||||
// Apply any transparency before attaching to scene
|
||||
if (n.opacity) {
|
||||
node.setMaterial(new THREE.MeshPhongMaterial({transparent: true, opacity: n.opacity, color: '#fff'}));
|
||||
}
|
||||
|
||||
node.attachToRoot();
|
||||
|
||||
if (n.isMain) {
|
||||
@@ -269,6 +275,7 @@ Scene.loadNodes = function (nodes) {
|
||||
AppState.clipping.boundingSphere = node.getBound();
|
||||
}
|
||||
|
||||
|
||||
AppState.nodes.push({id: n.label, active: true});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
* @namespace AppState
|
||||
*/
|
||||
let AppState = {
|
||||
// The Leaflet map object
|
||||
map : null,
|
||||
// The root scene object
|
||||
root: null,
|
||||
nodeIds: [],
|
||||
// {id: String, active: Boolean}
|
||||
nodes: [],
|
||||
mainNodeId: null,
|
||||
currentScene: null,
|
||||
sceneHasAudio: false,
|
||||
layersMenuBuilt: false,
|
||||
initialRotation: null,
|
||||
camera: null,
|
||||
@@ -15,7 +18,6 @@ let AppState = {
|
||||
ambientOcclusion : true,
|
||||
shadows : true,
|
||||
lightProbe : false,
|
||||
map : null,
|
||||
clipping : {
|
||||
enabled: false,
|
||||
plane : null,
|
||||
|
||||
62
js/ui.js
62
js/ui.js
@@ -7,6 +7,35 @@ import AppState from "./state.js";
|
||||
const UI = {};
|
||||
|
||||
UI.domParser = new DOMParser;
|
||||
|
||||
UI.contentMenuTabs = `
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-pills" id="content-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="layer-tab" data-bs-toggle="tab" data-bs-target="#layer" type="button" role="tab" aria-controls="layer" aria-selected="false">
|
||||
<i class="bi bi-boxes me-1"></i> Elementi 3D
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="media-tab" data-bs-toggle="tab" data-bs-target="#media" type="button" role="tab" aria-controls="media" aria-selected="true">
|
||||
<i class="bi bi-diagram-3 me-1"></i> Contenuti
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active p-3" id="layer" role="tabpanel" aria-labelledby="layer-tab" tabindex="0"></div>
|
||||
<div class="tab-pane p-3" id="media" role="tabpanel" aria-labelledby="media-tab" tabindex="0"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
UI.audioExample = `
|
||||
<button type="button" id="audio-example" class="text-left btn aton-btn fs-6 mx-2" data-bs-toggle="modal" data-bs-target="#audio1">
|
||||
<i class="bi bi-play-btn me-2"></i> Esempio audio (<em>Che fiero costume</em>)
|
||||
</button>
|
||||
`;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} triggerSelector - Usually, the close modal trigger element(s) selector
|
||||
@@ -137,20 +166,11 @@ UI.toggleSettingsPanel = function(triggerId) {
|
||||
<label class="form-check-label" for="shadowsSwitch">Ombre <i class="bi bi-info-circle ms-2 c-hand" title=""></i></label>
|
||||
`;
|
||||
|
||||
const lightProbeSwitch = document.createElement('div');
|
||||
lightProbeSwitch.className = 'form-check form-switch ms-4 mt-2';
|
||||
lightProbeSwitch.innerHTML = `
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="lpSwitch" title="Abilita / disabilita mappa HDRi">
|
||||
<label class="form-check-label" for="lpSwitch">Mappa HDRi <em>(light probe)</em> <i class="bi bi-info-circle ms-2 c-hand"></i></label>
|
||||
`;
|
||||
|
||||
shadowsSwitch.querySelector('input[type="checkbox"').checked = AppState.shadows;
|
||||
ambientOcclSwitch.querySelector('input[type="checkbox"').checked = AppState.ambientOcclusion;
|
||||
lightProbeSwitch.querySelector('input[type="checkbox"').checked = AppState.lightProbe;
|
||||
|
||||
ATON.UI.elSidePanel.appendChild(ambientOcclSwitch);
|
||||
ATON.UI.elSidePanel.appendChild(shadowsSwitch);
|
||||
ATON.UI.elSidePanel.appendChild(lightProbeSwitch);
|
||||
|
||||
// TODO: move somewhere else...
|
||||
document.querySelector('#aoSwitch').addEventListener(
|
||||
@@ -168,18 +188,6 @@ UI.toggleSettingsPanel = function(triggerId) {
|
||||
AppState.shadows = checked;
|
||||
}
|
||||
);
|
||||
// Not working properly?
|
||||
document.querySelector('#lpSwitch').addEventListener(
|
||||
'change',
|
||||
event => {
|
||||
const checked = event.target.checked;
|
||||
ATON.setAutoLP(checked);
|
||||
//if (!checked) ATON.clearLightProbes();
|
||||
AppState.lightProbe = checked;
|
||||
if (checked) ATON.updateLightProbes();
|
||||
console.log('Light probe: ', checked);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -214,15 +222,15 @@ UI.createLightSlider = function(direction, label, range, step) {
|
||||
*/
|
||||
UI.toggleContentMenu = function(triggerId) {
|
||||
const btn = document.querySelector(`#${triggerId}`);
|
||||
let audio1 = this.domParser.parseFromString(config.menu.audioBtn1, 'text/html');
|
||||
audio1 = audio1.querySelector('button');
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
ATON.UI.setSidePanelRight();
|
||||
ATON.UI.showSidePanel({header: '<i class="bi bi-music-note-list me-1"></i> Contenuti'});
|
||||
ATON.UI.elSidePanel.appendChild(audio1);
|
||||
ATON.UI.elSidePanel.appendChild(this.domParser.parseFromString('<h5 class="ms-3">Layer</h5>', 'text/html').querySelector('h5'));
|
||||
this.buildLayersMenu(AppState.nodes, ATON.UI.elSidePanel);
|
||||
ATON.UI.showSidePanel({header: 'Menu'});
|
||||
// Append tabs, then tab panes
|
||||
const tabs = this.domParser.parseFromString(UI.contentMenuTabs, 'text/html');
|
||||
ATON.UI.elSidePanel.appendChild(tabs.querySelector('#content-tabs'));
|
||||
ATON.UI.elSidePanel.appendChild(tabs.querySelector('.tab-content'));
|
||||
this.buildLayersMenu(AppState.nodes, ATON.UI.elSidePanel.querySelector('#layer'));
|
||||
});
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TODO CSS-only popover -->
|
||||
<div class="card d-none" id="shadows-popover" popover>Disabilitare le ombre può migliorare le prestazioni</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import Scene from "../../js/scene.js";
|
||||
import { config } from "../../config.js";
|
||||
import AppState from "../../js/state.js";
|
||||
|
||||
AppState.currentScene = 'salvador';
|
||||
AppState.sceneHasAudio = true;
|
||||
|
||||
Scene.openScene(config.markers.find(m => m.id === 'salvador'));
|
||||
Scene.UI.pauseAudio('[data-bs-dismiss="modal"]');
|
||||
@@ -1,4 +1,6 @@
|
||||
import Scene from "../../js/scene.js";
|
||||
import { config } from "../../config.js";
|
||||
import AppState from "../../js/state.js";
|
||||
|
||||
AppState.currentScene = 'ssgp';
|
||||
Scene.openScene(config.markers.find(m => m.id === 'ssgp'));
|
||||
Reference in New Issue
Block a user