Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GeoVistoogsi
AR
Commits
c468418f
Commit
c468418f
authored
2 months ago
by
Cantuerk
Browse files
Options
Download
Email Patches
Plain Diff
Update public/index.html
parent
4ac75a0a
master
21caog1bif-master-patch-96693
1 merge request
!179
Update public/index.html
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
public/index.html
+148
-105
public/index.html
with
148 additions
and
105 deletions
+148
-105
public/index.html
+
148
-
105
View file @
c468418f
...
...
@@ -94,40 +94,43 @@
</div>
</div>
<script
src=
"ar_debug_console.js"
></script>
<link
rel=
"stylesheet"
href=
"https://unpkg.com/leaflet/dist/leaflet.css"
/>
<script
src=
"https://unpkg.com/leaflet/dist/leaflet.js"
></script>
<!-- Leaflet einbinden -->
<script
src=
"ar_overviewmap.js"
></script>
<!-- Audio-Element für Button-Klick -->
<audio
id=
"button-sound"
src=
"sounds/button-sound.mp3"
preload=
"auto"
></audio>
<audio
id=
"button-sound"
src=
"sounds/button-sound.mp3"
preload=
"auto"
></audio>
<!-- Audio-Element für Button-Klick -->
<script>
// Variablen
let
selectedModel
=
'
robot
'
;
/* ========================= */
/* GLOBALE VARIABLEN */
/* ========================= */
let
selectedPlacedModel
=
null
;
let
currentSession
=
null
;
let
reticle
=
null
;
let
scene
,
camera
;
const
menus
=
[
'
menu-bar
'
,
'
add-menu
'
,
'
edit-menu
'
,
'
options-menu
'
,
'
map-window
'
];
/* ========================= */
/* MODELLE */
/* ========================= */
let
models
=
{
bench
:
{
name
:
"
Bench
"
,
image
:
"
previewImages/bench.PNG
"
,
file
:
"
https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/bench_model/scene.gltf
"
,
scale
:
{
x
:
0.1
,
y
:
0.1
,
z
:
0.1
},
minScale
:
0.05
,
// 50% der aktuellen Größe
maxScale
:
0.5
// 500% der aktuellen Größe
minScale
:
0.05
,
maxScale
:
0.5
},
trashbin
:
{
name
:
"
Trash bin
"
,
image
:
"
previewImages/trash_can.PNG
"
,
file
:
"
https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/trash_model/scene.gltf
"
,
scale
:
{
x
:
0.03
,
y
:
0.03
,
z
:
0.03
},
minScale
:
0.01
,
// 50% der aktuellen Größe
maxScale
:
0.1
// 500% der aktuellen Größe
minScale
:
0.01
,
maxScale
:
0.1
},
lantern
:
{
name
:
"
Lantern
"
,
...
...
@@ -171,12 +174,14 @@
}
};
const
menus
=
[
'
menu-bar
'
,
'
add-menu
'
,
'
edit-menu
'
,
'
options-menu
'
,
'
map-window
'
];
/* ========================= */
/* INITIALISIERUNG */
/* ========================= */
window
.
onload
=
()
=>
{
initializeAddMenu
();
//
Fügt Sound zu allen Buttons hinzu
//
Allen Buttons den Sound hinzufügen
const
buttons
=
document
.
querySelectorAll
(
"
button, .menu-item
"
);
buttons
.
forEach
(
button
=>
{
button
.
addEventListener
(
"
click
"
,
playButtonSound
);
...
...
@@ -201,6 +206,10 @@
`
;
}
/* ========================= */
/* MENÜ-STEUERUNG */
/* ========================= */
function
showMenu
(
menuId
)
{
menus
.
forEach
(
id
=>
{
document
.
getElementById
(
id
).
style
.
display
=
id
===
menuId
?
'
flex
'
:
'
none
'
;
...
...
@@ -210,25 +219,15 @@
else
if
(
menuId
===
'
map-window
'
)
init_map
();
}
function
clearSelectedModel
()
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
{
child
.
material
.
emissive
.
setHex
(
0x000000
);
// Markierung entfernen
}
});
selectedPlacedModel
=
null
;
// Kein Modell mehr ausgewählt
}
function
closeDynamicMenu
()
{
const
dynamicMenu
=
document
.
getElementById
(
"
dynamic-menu
"
);
dynamicMenu
.
style
.
display
=
"
none
"
;
}
function
selectModel
(
modelId
)
{
const
model
=
models
[
modelId
];
if
(
model
&&
model
.
file
)
{
loadModel
(
model
.
file
);
showMenu
(
'
menu-bar
'
);
}
}
/* ========================= */
/* MODELL-HANDLING */
/* ========================= */
function
loadModel
(
filePath
)
{
const
modelConfig
=
Object
.
values
(
models
).
find
(
model
=>
model
.
file
===
filePath
);
const
loader
=
new
THREE
.
GLTFLoader
();
...
...
@@ -256,30 +255,11 @@
);
}
function
highlightSelectedModel
()
{
if
(
selectedPlacedModel
)
{
removeHighlightFromAllModels
();
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
{
child
.
material
.
emissive
.
setHex
(
0xff0000
);
// Rote Hervorhebung
}
});
}
}
function
removeHighlightFromAllModels
()
{
scene
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
&&
child
.
material
&&
child
.
material
.
emissive
)
{
child
.
material
.
emissive
.
setHex
(
0x000000
);
// Markierung entfernen
}
});
}
function
removeHighlightFromSelectedModel
()
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
child
.
material
.
emissive
.
setHex
(
0x000000
);
// Markierung entfernen
});
function
selectModel
(
modelId
)
{
const
model
=
models
[
modelId
];
if
(
model
&&
model
.
file
)
{
loadModel
(
model
.
file
);
showMenu
(
'
menu-bar
'
);
}
}
...
...
@@ -305,7 +285,7 @@
// Überprüfe, ob das ausgewählte Objekt das Reticle ist
if
(
selectedObject
===
reticle
)
{
console
.
log
(
"
Reticle kann nicht ausgewählt werden.
"
);
return
;
// Auswahl ignorieren
return
;
}
// Markiere das gesamte Modell als ausgewählt
...
...
@@ -315,6 +295,56 @@
}
}
function
clearSelectedModel
()
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
{
child
.
material
.
emissive
.
setHex
(
0x000000
);
// Markierung entfernen
}
});
selectedPlacedModel
=
null
;
}
}
function
highlightSelectedModel
()
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
{
child
.
material
.
emissive
.
setHex
(
0xff0000
);
// Rote Hervorhebung
}
});
}
}
function
removeHighlightFromSelectedModel
()
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
traverse
((
child
)
=>
{
if
(
child
.
isMesh
)
child
.
material
.
emissive
.
setHex
(
0x000000
);
// Markierung entfernen
});
}
}
function
deleteModel
()
{
if
(
!
selectedPlacedModel
)
{
console
.
log
(
"
Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es löschen.
"
);
return
;
}
const
deleteDialog
=
document
.
getElementById
(
'
delete-confirmation-dialog
'
);
deleteDialog
.
style
.
display
=
'
flex
'
;
}
function
confirmDelete
(
shouldDelete
)
{
const
deleteDialog
=
document
.
getElementById
(
'
delete-confirmation-dialog
'
);
deleteDialog
.
style
.
display
=
'
none
'
;
if
(
shouldDelete
&&
selectedPlacedModel
)
{
scene
.
remove
(
selectedPlacedModel
);
selectedPlacedModel
=
null
;
showMenu
(
'
menu-bar
'
);
}
}
function
completeEditing
()
{
removeHighlightFromSelectedModel
();
closeDynamicMenu
();
...
...
@@ -323,14 +353,17 @@
document
.
getElementById
(
'
menu-bar
'
).
style
.
display
=
'
flex
'
;
}
/* ========================= */
/* BEARBEITUNGS-MENÜS */
/* ========================= */
function
openRotationMenu
()
{
if
(
!
selectedPlacedModel
)
{
console
.
log
(
"
Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es bearbeiten.
"
);
return
;
}
// Holen Sie die aktuelle Y-Rotation des Modells (in Grad)
const
currentRotation
=
Math
.
round
(
THREE
.
MathUtils
.
radToDeg
(
selectedPlacedModel
.
rotation
.
y
));
const
currentRotation
=
Math
.
round
(
THREE
.
MathUtils
.
radToDeg
(
selectedPlacedModel
.
rotation
.
y
));
// Aktuelle Y-Rotation des Modells (in Grad)
const
dynamicMenu
=
document
.
getElementById
(
"
dynamic-menu
"
);
dynamicMenu
.
style
.
display
=
"
flex
"
;
...
...
@@ -346,7 +379,7 @@
const
radians
=
(
value
/
180
)
*
Math
.
PI
;
selectedPlacedModel
.
rotation
[
axis
]
=
radians
;
//
Updat
e der aktuellen Rotation im
Menü
//
Anzeig
e der aktuellen Rotation im
Dynamic-Menü aktualisieren
const
currentRotationDisplay
=
document
.
getElementById
(
"
current-rotation
"
);
if
(
currentRotationDisplay
)
{
currentRotationDisplay
.
textContent
=
value
;
// Zeige den aktuellen Wert in Grad an
...
...
@@ -360,37 +393,40 @@
return
;
}
// Aktuelle Skalierung
des Modells
bestimmen
// Aktuelle Skalierung
und Grenzen
bestimmen
const
currentScale
=
selectedPlacedModel
.
scale
.
x
;
const
minScale
=
selectedPlacedModel
.
modelConfig
.
minScale
;
const
maxScale
=
selectedPlacedModel
.
modelConfig
.
maxScale
;
const
step
=
(
maxScale
-
minScale
)
/
100
;
// Dynamische Schrittgröße basierend auf Grenzen
cons
ole
.
log
(
"
Slider-Werte:
"
,
{
minScale
,
maxScale
,
currentScale
});
cons
t
currentScalePercent
=
((
currentScale
-
minScale
)
/
(
maxScale
-
minScale
))
*
100
;
// Umrechnung der Werte in Prozent
const
dynamicMenu
=
document
.
getElementById
(
"
dynamic-menu
"
);
dynamicMenu
.
style
.
display
=
"
flex
"
;
dynamicMenu
.
innerHTML
=
`
<h3>Skalierung anpassen</h3>
<label>Größe: <span id="scale-value">
${
currentScale
.
toFixed
(
2
)}
</span>
<input type="range" min="
${
minScale
}
" max="
${
maxScale
}
" step="
${
step
}
" value="
${
currentScale
}
" onchange="updateScale(this.value)"></label>
<button onclick="closeDynamicMenu()">Zurück</button>
`
;
<h3>Skalierung anpassen</h3>
<label>Größe: <span id="scale-value">
${
currentScale
Percent
.
toFixed
(
0
)}
%
</span>
<input type="range" min="
0" max="100
" step="
1
" value="
${
currentScale
Percent
}
" onchange="updateScale(this.value
,
${
minScale
}
,
${
maxScale
}
)"></label>
<button onclick="closeDynamicMenu()">Zurück</button>
`
;
}
function
updateScale
(
valu
e
)
{
function
updateScale
(
percentValue
,
minScale
,
maxScal
e
)
{
if
(
selectedPlacedModel
)
{
const
scale
=
parseFloat
(
value
);
// Berechnung der Skalierung basierend auf dem Prozentwert
const
scale
=
minScale
+
(
percentValue
/
100
)
*
(
maxScale
-
minScale
);
selectedPlacedModel
.
scale
.
set
(
scale
,
scale
,
scale
);
// Anzeige des aktuellen
Wertes
aktualisieren
// Anzeige des aktuellen
Prozentsatzes im Dynamic-Menü
aktualisieren
const
scaleValueDisplay
=
document
.
getElementById
(
"
scale-value
"
);
if
(
scaleValueDisplay
)
{
scaleValueDisplay
.
textContent
=
`
${
scale
.
toFixed
(
2
)}
`
;
scaleValueDisplay
.
textContent
=
`
${
parseInt
(
percentValue
,
10
)}
%
`
;
}
}
}
let
moveDelta
=
0.1
;
// Standardwert für die Verschiebungsgröße, kann mit dem Slider geändert werden
function
openMoveMenu
()
{
if
(
!
selectedPlacedModel
)
{
console
.
log
(
"
Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es bewegen.
"
);
...
...
@@ -399,58 +435,56 @@
const
dynamicMenu
=
document
.
getElementById
(
"
dynamic-menu
"
);
dynamicMenu
.
style
.
display
=
"
flex
"
;
dynamicMenu
.
innerHTML
=
`
<h3>Modell bewegen</h3>
<div>
<button onclick="moveModel('x', -0.1)">← X</button>
<button onclick="moveModel('x', 0.1)">→ X</button>
<div id="position-info">
<p>Aktuelle Position: X=
${
selectedPlacedModel
.
position
.
x
.
toFixed
(
2
)}
, Z=
${
selectedPlacedModel
.
position
.
z
.
toFixed
(
2
)}
</p>
</div>
<div>
<button onclick="moveModel('y', -0.1)">↓ Y</button>
<button onclick="moveModel('y', 0.1)">↑ Y</button>
<p>Verschiebungsgröße: <span id="move-delta-display">
${
moveDelta
.
toFixed
(
2
)}
</span></p>
<input type="range" min="0.01" max="1.0" step="0.01" value="
${
moveDelta
}
"
onchange="updateMoveDelta(this.value)">
</div>
<div>
<button onclick="moveModel('z', -0.1)">- Z</button>
<button onclick="moveModel('z', 0.1)">+ Z</button>
<div style="display: flex; flex-direction: column; align-items: center; gap: 10px;">
<div>
<button onclick="moveModel('x', -moveDelta)">← X</button>
<button onclick="moveModel('x', moveDelta)">→ X</button>
</div>
<div>
<button onclick="moveModel('z', -moveDelta)">- Z</button>
<button onclick="moveModel('z', moveDelta)">+ Z</button>
</div>
</div>
<button onclick="closeDynamicMenu()">Zurück</button>
`
;
}
function
moveModel
(
axis
,
delta
)
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
position
[
axis
]
+=
delta
;
function
updateMoveDelta
(
value
)
{
moveDelta
=
parseFloat
(
value
);
const
moveDeltaDisplay
=
document
.
getElementById
(
"
move-delta-display
"
);
if
(
moveDeltaDisplay
)
{
moveDeltaDisplay
.
textContent
=
moveDelta
.
toFixed
(
2
);
}
}
function
moveModel
(
axis
,
delta
)
{
if
(
selectedPlacedModel
)
{
selectedPlacedModel
.
position
[
axis
]
+=
delta
;
// Bewegung durchführen
function
deleteModel
()
{
if
(
!
selectedPlacedModel
)
{
console
.
log
(
"
Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es löschen.
"
);
return
;
}
// Dialog anzeigen
const
deleteDialog
=
document
.
getElementById
(
'
delete-confirmation-dialog
'
);
deleteDialog
.
style
.
display
=
'
flex
'
;
}
function
confirmDelete
(
shouldDelete
)
{
const
deleteDialog
=
document
.
getElementById
(
'
delete-confirmation-dialog
'
);
deleteDialog
.
style
.
display
=
'
none
'
;
if
(
shouldDelete
&&
selectedPlacedModel
)
{
scene
.
remove
(
selectedPlacedModel
);
selectedPlacedModel
=
null
;
showMenu
(
'
menu-bar
'
);
// Positionsanzeige im Dynamic-Menü aktualisieren
const
positionInfo
=
document
.
getElementById
(
"
position-info
"
);
if
(
positionInfo
)
{
positionInfo
.
innerHTML
=
`
<p>Aktuelle Position: X=
${
selectedPlacedModel
.
position
.
x
.
toFixed
(
2
)}
, Z=
${
selectedPlacedModel
.
position
.
z
.
toFixed
(
2
)}
</p>`
;
}
}
}
function
closeDynamicMenu
()
{
const
dynamicMenu
=
document
.
getElementById
(
"
dynamic-menu
"
);
dynamicMenu
.
style
.
display
=
"
none
"
;
}
/* ========================= */
/* KARTENSTEUERUNG */
/* ========================= */
function
refreshMapDialog
()
{
const
mapDialog
=
document
.
getElementById
(
'
map-dialog
'
);
mapDialog
.
style
.
display
=
'
flex
'
;
...
...
@@ -461,6 +495,10 @@
mapDialog
.
style
.
display
=
'
none
'
;
}
/* ========================= */
/* AR-HANDLING */
/* ========================= */
async
function
activateXR
()
{
const
canvas
=
document
.
createElement
(
'
canvas
'
);
document
.
body
.
appendChild
(
canvas
);
...
...
@@ -498,6 +536,7 @@
currentSession
.
addEventListener
(
"
end
"
,
()
=>
{
currentSession
=
null
;
document
.
getElementById
(
"
dynamic-menu
"
).
style
.
display
=
"
none
"
;
menus
.
forEach
(
id
=>
{
document
.
getElementById
(
id
).
style
.
display
=
'
none
'
;
});
...
...
@@ -537,14 +576,15 @@
}
function
confirmExit
(
shouldExit
)
{
if
(
shouldExit
&&
currentSession
)
{
currentSession
.
end
();
}
if
(
shouldExit
&&
currentSession
)
currentSession
.
end
();
document
.
getElementById
(
'
confirmation-dialog
'
).
style
.
display
=
'
none
'
;
}
let
soundTimeout
=
false
;
/* ========================= */
/* BENUTZERINTERAKTIONEN */
/* ========================= */
let
soundTimeout
=
false
;
function
playButtonSound
()
{
if
(
!
soundTimeout
)
{
const
sound
=
document
.
getElementById
(
"
button-sound
"
);
...
...
@@ -559,6 +599,9 @@
}
/* ========================= */
/* DEBUGGING UND START */
/* ========================= */
if
(
navigator
.
xr
)
{
const
startButton
=
document
.
createElement
(
'
button
'
);
startButton
.
textContent
=
'
Start AR
'
;
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets