Commit 67715bc3 authored by Cantuerk's avatar Cantuerk
Browse files

Update public/ar_main.js

parent 9d0b421b
1 merge request!184Update public/ar_main.js
Showing with 370 additions and 360 deletions
+370 -360
/* ========================= */
/* GLOBALE VARIABLEN */
/* ========================= */
let selectedPlacedModel = null;
let currentSession = null;
let reticle = null;
let scene, camera;
let geoLocation;
const menus = ['menu-bar', 'add-menu', 'edit-menu', 'options-menu', 'map-window'];
/* ========================= */
/* MODELLE */
/* ========================= */
let models = {
/* ========================= */
/* GLOBALE VARIABLEN */
/* ========================= */
let selectedPlacedModel = null;
let currentSession = null;
let reticle = null;
let scene, camera;
let geoLocation;
const menus = ['menu-bar', 'add-menu', 'edit-menu', 'options-menu', 'map-window'];
/* ========================= */
/* MODELLE */
/* ========================= */
let models = {
bench: {
name: "Bench",
image: "previewImages/bench.PNG",
image: "assets/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,
......@@ -22,7 +22,7 @@
},
trashbin: {
name: "Trash bin",
image: "previewImages/trash_can.PNG",
image: "assets/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,
......@@ -30,7 +30,7 @@
},
lantern: {
name: "Lantern",
image: "previewImages/park_light.png",
image: "assets/previewImages/park_light.png",
file: "https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/park_light_model/scene.gltf",
scale: { x: 0.5, y: 0.5, z: 0.5 },
minScale: 0.2,
......@@ -38,7 +38,7 @@
},
telephone_box: {
name: "Telephone Box",
image: "previewImages/telephone_box.PNG",
image: "assets/previewImages/telephone_box.PNG",
file: "https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/telephone_box_model/scene.gltf",
scale: { x: 0.5, y: 0.5, z: 0.5 },
minScale: 0.05,
......@@ -46,7 +46,7 @@
},
fire_hydrant_model: {
name: "Fire Hydrant",
image: "previewImages/hydrant.PNG",
image: "assets/previewImages/hydrant.PNG",
file: "https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/fire_hydrant_model/scene.gltf",
scale: { x: 0.3, y: 0.3, z: 0.3 },
minScale: 0.1,
......@@ -54,7 +54,7 @@
},
statue: {
name: "Statue",
image: "previewImages/statue.PNG",
image: "assets/previewImages/statue.PNG",
file: "https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/statue_model/scene.gltf",
scale: { x: 0.5, y: 0.5, z: 0.5 },
minScale: 0.05,
......@@ -62,18 +62,18 @@
},
fountain: {
name: "Fountain",
image: "previewImages/fountain.PNG",
image: "assets/previewImages/fountain.PNG",
file: "https://transfer.hft-stuttgart.de/gitlab/geovistoogsi/ar/-/raw/master/public/assets/models/fountain_model/scene.gltf",
scale: { x: 0.001, y: 0.001, z: 0.001 },
minScale: 0.0005,
maxScale: 0.005
}
};
};
/* ========================= */
/* INITIALISIERUNG */
/* ========================= */
window.onload = () => {
/* ========================= */
/* INITIALISIERUNG */
/* ========================= */
window.onload = () => {
initializeAddMenu();
// Allen Buttons den Sound hinzufügen
......@@ -81,9 +81,9 @@
buttons.forEach(button => {
button.addEventListener("click", playButtonSound);
});
};
};
function initializeAddMenu() {
function initializeAddMenu() {
const addMenu = document.getElementById('add-menu');
addMenu.innerHTML = Object.entries(models)
.map(
......@@ -96,15 +96,15 @@
.join('') +
`
<div class="menu-item" onclick="showMenu('menu-bar')">
<img src="previewImages/back-icon.png" alt="Zurück" />
<img src="assets/icons/back-icon.png" alt="Zurück" />
</div>
`;
}
}
/* ========================= */
/* MENÜ-STEUERUNG */
/* ========================= */
function showMenu(menuId) {
/* ========================= */
/* MENÜ-STEUERUNG */
/* ========================= */
function showMenu(menuId) {
const isMapWindow = menuId === 'map-window';
if (isMapWindow && !geoLocation) {
console.log("Standort nicht geladen");
......@@ -118,29 +118,29 @@
closeDynamicMenu();
if (menuId === 'menu-bar') clearSelectedModel();
else if (isMapWindow) init_map();
}
}
function closeDynamicMenu() {
function closeDynamicMenu() {
const dynamicMenu = document.getElementById("dynamic-menu");
dynamicMenu.style.display = "none";
}
}
/* ========================= */
/* MODELL-HANDLING */
/* ========================= */
function getAllPlacedModels() {
/* ========================= */
/* MODELL-HANDLING */
/* ========================= */
function getAllPlacedModels() {
return scene.children.filter(child => child.isPlacedModel === true);
}
}
function loadModel(filePath) {
function loadModel(filePath) {
placeModel(filePath, reticle.position, (model) => {
selectedPlacedModel = model;
highlightSelectedModel();
showMenu('edit-menu');
});
}
}
function placeModel(filePath, position, onPlace = null) {
function placeModel(filePath, position, onPlace = null) {
const modelConfig = Object.values(models).find(model => model.file === filePath);
const loader = new THREE.GLTFLoader();
loader.load(
......@@ -164,17 +164,17 @@
console.error("Fehler beim Laden des Modells:", error);
}
);
}
}
function selectModel(modelId) {
function selectModel(modelId) {
const model = models[modelId];
if (model && model.file) {
loadModel(model.file);
showMenu('menu-bar');
}
}
}
function selectModelFromScene(event) {
function selectModelFromScene(event) {
const mouse = new THREE.Vector2(
(event.clientX / window.innerWidth) * 2 - 1,
-(event.clientY / window.innerHeight) * 2 + 1
......@@ -204,9 +204,9 @@
highlightSelectedModel();
showMenu("edit-menu");
}
}
}
function clearSelectedModel() {
function clearSelectedModel() {
if (selectedPlacedModel) {
selectedPlacedModel.traverse((child) => {
if (child.isMesh) {
......@@ -215,9 +215,9 @@
});
selectedPlacedModel = null;
}
}
}
function highlightSelectedModel() {
function highlightSelectedModel() {
if (selectedPlacedModel) {
removeHighlightFromAllModels();
selectedPlacedModel.traverse((child) => {
......@@ -226,26 +226,26 @@
}
});
}
}
}
function removeHighlightFromSelectedModel() {
function removeHighlightFromSelectedModel() {
if (selectedPlacedModel) {
selectedPlacedModel.traverse((child) => {
if (child.isMesh) child.material.emissive.setHex(0x000000); // Markierung entfernen
});
}
}
}
function removeHighlightFromAllModels() {
function removeHighlightFromAllModels() {
scene.traverse((child) => {
if (child.isMesh && child.material && child.material.emissive) {
child.material.emissive.setHex(0x000000); // Markierung entfernen
}
});
}
}
function deleteModel() {
function deleteModel() {
if (!selectedPlacedModel) {
console.log("Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es löschen.");
return;
......@@ -253,9 +253,9 @@
const deleteDialog = document.getElementById('delete-confirmation-dialog');
deleteDialog.style.display = 'flex';
}
}
function confirmDelete(shouldDelete) {
function confirmDelete(shouldDelete) {
const deleteDialog = document.getElementById('delete-confirmation-dialog');
deleteDialog.style.display = 'none';
......@@ -264,20 +264,20 @@
selectedPlacedModel = null;
showMenu('menu-bar');
}
}
}
function completeEditing() {
function completeEditing() {
removeHighlightFromSelectedModel();
closeDynamicMenu();
selectedPlacedModel = null;
document.getElementById('edit-menu').style.display = 'none';
document.getElementById('menu-bar').style.display = 'flex';
}
}
/* ========================= */
/* BEARBEITUNGS-MENÜS */
/* ========================= */
function openRotationMenu() {
/* ========================= */
/* 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;
......@@ -292,9 +292,9 @@
<label>Y-Achse: <span id="current-rotation">${currentRotation}</span>°<input type="range" min="0" max="360" step="10" onchange="updateRotation('y', this.value)"></label>
<button onclick="closeDynamicMenu()">Zurück</button>
`;
}
}
function updateRotation(axis, value) {
function updateRotation(axis, value) {
if (selectedPlacedModel) {
const radians = (value / 180) * Math.PI;
selectedPlacedModel.rotation[axis] = radians;
......@@ -305,9 +305,9 @@
currentRotationDisplay.textContent = value; // Zeige den aktuellen Wert in Grad an
}
}
}
}
function openScaleMenu() {
function openScaleMenu() {
if (!selectedPlacedModel) {
console.log("Kein Modell ausgewählt. Bitte wählen Sie ein Modell aus, bevor Sie es bearbeiten.");
return;
......@@ -326,12 +326,12 @@
dynamicMenu.innerHTML = `
<h3>Skalierung anpassen</h3>
<label>Größe: <span id="scale-value">${currentScalePercent.toFixed(0)}%</span>
<input type="range" min="0" max="100" step="1" value="${currentScalePercent}" onchange="updateScale(this.value, ${minScale}, ${maxScale})"></label>
<input type="range" min="0" max="100" step=""${step}"" value="${currentScalePercent}" onchange="updateScale(this.value, ${minScale}, ${maxScale})"></label>
<button onclick="closeDynamicMenu()">Zurück</button>
`;
}
}
function updateScale(percentValue, minScale, maxScale) {
function updateScale(percentValue, minScale, maxScale) {
if (selectedPlacedModel) {
// Berechnung der Skalierung basierend auf dem Prozentwert
const scale = minScale + (percentValue / 100) * (maxScale - minScale);
......@@ -343,9 +343,7 @@
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) {
......@@ -358,62 +356,74 @@ function openMoveMenu() {
dynamicMenu.innerHTML = `
<h3>Modell bewegen</h3>
<label>
Aktuelle Position: X=${selectedPlacedModel.position.x.toFixed(2)}, Z=${selectedPlacedModel.position.z.toFixed(2)}
</label>
<label>
Verschiebungsgröße: <span id="move-delta-display">${moveDelta.toFixed(2)}</span>
<input type="range" min="0.01" max="1.0" step="0.01" value="${moveDelta}" onchange="updateMoveDelta(this.value)">
</label>
<div style="display: flex; gap: 4px;">
<button onclick="moveModelDynamic('x', -1)">← X</button>
<button onclick="moveModelDynamic('x', 1)">→ X</button>
<button onclick="moveModelDynamic('z', -1)">- Z</button>
<button onclick="moveModelDynamic('z', 1)">+ Z</button>
<div id="joystick-container" style="position: relative; width: 100px; height: 100px; border: 2px solid #ccc; border-radius: 50%; margin: 20px auto;">
<div id="joystick-knob" style="position: absolute; width: 30px; height: 30px; background: #007BFF; border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%);"></div>
</div>
<button onclick="closeDynamicMenu()">Zurück</button>
`;
}
function updateMoveDelta(value) {
moveDelta = parseFloat(value);
const moveDeltaDisplay = document.getElementById("move-delta-display");
if (moveDeltaDisplay) {
moveDeltaDisplay.textContent = moveDelta.toFixed(2);
}
}
const container = document.getElementById("joystick-container");
const knob = document.getElementById("joystick-knob");
let isDragging = false;
function moveModelDynamic(axis, direction) {
if (selectedPlacedModel) {
const delta = direction * moveDelta; // Dynamischer Wert basierend auf Slider
selectedPlacedModel.position[axis] += delta;
const center = { x: container.offsetWidth / 2, y: container.offsetHeight / 2 };
const maxDistance = container.offsetWidth / 2;
// Position im 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>`;
}
}
}
knob.addEventListener("mousedown", () => (isDragging = true));
document.addEventListener("mouseup", () => {
isDragging = false;
knob.style.left = "50%";
knob.style.top = "50%";
moveModelDynamic('x', 0); // Bewegung stoppen, wenn Maus losgelassen wird
moveModelDynamic('z', 0);
});
document.addEventListener("mousemove", (event) => {
if (!isDragging) return;
const rect = container.getBoundingClientRect();
const dx = event.clientX - rect.left - center.x;
const dy = event.clientY - rect.top - center.y;
const distance = Math.min(Math.sqrt(dx * dx + dy * dy), maxDistance);
const angle = Math.atan2(dy, dx);
const offsetX = Math.cos(angle) * distance;
const offsetY = Math.sin(angle) * distance;
/* ========================= */
/* KARTENSTEUERUNG */
/* ========================= */
function refreshMapDialog() {
// Knopfposition aktualisieren
knob.style.left = `${center.x + offsetX}px`;
knob.style.top = `${center.y + offsetY}px`;
// Bewegung basierend auf Joystick-Position anwenden
const normalizedX = offsetX / maxDistance;
const normalizedY = offsetY / maxDistance;
moveModelDynamic('x', normalizedX * 0.1); // Feine Anpassung
moveModelDynamic('z', -normalizedY * 0.1); // Feine Anpassung
});
}
function moveModelDynamic(axis, value) {
if (selectedPlacedModel) selectedPlacedModel.position[axis] += value;
}
/* ========================= */
/* KARTENSTEUERUNG */
/* ========================= */
function refreshMapDialog() {
const mapDialog = document.getElementById('map-dialog');
mapDialog.style.display = 'flex';
}
}
function closeMapDialog() {
function closeMapDialog() {
const mapDialog = document.getElementById('map-dialog');
mapDialog.style.display = 'none';
}
}
/* ========================= */
/* AR-HANDLING */
/* ========================= */
async function activateXR(sceneData = null) {
/* ========================= */
/* AR-HANDLING */
/* ========================= */
async function activateXR(sceneData = null) {
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const gl = canvas.getContext('webgl', { xrCompatible: true });
......@@ -487,9 +497,9 @@ function openMoveMenu() {
}
});
}
}, function(error) {
}, function (error) {
console.error("Fehler bei der Geolokalisierung:", JSON.stringify(error));
}, {enableHighAccuracy: true, maximumAge: 2000, timeout: 5000});
}, { enableHighAccuracy: true, maximumAge: 2000, timeout: 5000 });
}
currentSession.requestAnimationFrame(function onXRFrame(time, frame) {
......@@ -517,22 +527,22 @@ function openMoveMenu() {
renderer.render(scene, camera);
}
});
}
}
function exitAR() {
function exitAR() {
document.getElementById('confirmation-dialog').style.display = 'flex';
}
}
function confirmExit(shouldExit) {
function confirmExit(shouldExit) {
if (shouldExit && currentSession) currentSession.end();
document.getElementById('confirmation-dialog').style.display = 'none';
}
}
/* ========================= */
/* BENUTZERINTERAKTIONEN */
/* ========================= */
let soundTimeout = false;
function playButtonSound() {
/* ========================= */
/* BENUTZERINTERAKTIONEN */
/* ========================= */
let soundTimeout = false;
function playButtonSound() {
if (!soundTimeout) {
const sound = document.getElementById("button-sound");
sound.currentTime = 0;
......@@ -543,4 +553,4 @@ function openMoveMenu() {
soundTimeout = false;
}, 200); // Verzögerung von 200ms
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment