Commit 9ecd2076 authored by Alfakhori's avatar Alfakhori
Browse files

v186.0.2

parent 5e700049
Pipeline #12489 passed with stage
in 26 seconds
import { showInfoDialog } from './ar_main.js';
function downloadScene() { function downloadScene() {
const placedModels = window.getAllPlacedModels().map(model => { const placedModels = window.getAllPlacedModels().map(model => {
const { lat, lng } = window.threeToLeaflet(model.position.x, model.position.z); const { lat, lng } = window.threeToLeaflet(model.position.x, model.position.z);
...@@ -17,6 +18,7 @@ function downloadScene() { ...@@ -17,6 +18,7 @@ function downloadScene() {
return; return;
} }
const geoLocation = window.getGeoLocation();
if (!geoLocation) { if (!geoLocation) {
console.log("Standort nicht geladen"); console.log("Standort nicht geladen");
showInfoDialog("Ihr Standort wurde noch nicht geladen"); showInfoDialog("Ihr Standort wurde noch nicht geladen");
......
...@@ -294,7 +294,7 @@ function closeDynamicMenu() { ...@@ -294,7 +294,7 @@ function closeDynamicMenu() {
} }
function showInfoDialog(message) { export function showInfoDialog(message) {
const infoDialog = const infoDialog =
document.getElementById( document.getElementById(
...@@ -1123,131 +1123,86 @@ function closeMapDialog() { ...@@ -1123,131 +1123,86 @@ function closeMapDialog() {
async function activateXR(sceneData = null) { async function activateXR(sceneData = null) {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
document.body.appendChild(canvas); document.body.appendChild(canvas);
// ======================================================== // Keep the original WebXR rendering architecture.
// Three.js WebXR renderer // Three.js r186 is used only as the renderer/scene library;
// ======================================================== // WebXR session, hit-test source, framebuffer and camera pose
// are still controlled explicitly as in the working r126 version.
const gl = canvas.getContext("webgl", {
xrCompatible: true,
alpha: true,
antialias: true,
});
if (!gl) {
throw new Error("WebGL konnte nicht initialisiert werden.");
}
const renderer = new THREE.WebGLRenderer({ const renderer = new THREE.WebGLRenderer({
alpha: true, alpha: true,
antialias: true,
canvas, canvas,
context: gl,
antialias: true,
}); });
renderer.autoClear = false; renderer.autoClear = false;
renderer.xr.enabled = true;
xrRenderer = renderer; xrRenderer = renderer;
// Keep the same reference-space type used by the previous
// manual WebXR implementation.
renderer.xr.setReferenceSpaceType("local");
scene = new THREE.Scene(); scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(); camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;
// ========================================================
// AR lighting
// ========================================================
const ambientLight = new THREE.AmbientLight(0xffffff, 2.5); const ambientLight = new THREE.AmbientLight(0xffffff, 2.5);
scene.add(ambientLight); scene.add(ambientLight);
const hemisphereLight = const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x888888, 1.5);
new THREE.HemisphereLight(0xffffff, 0x888888, 1.5);
scene.add(hemisphereLight); scene.add(hemisphereLight);
const directionalLight = const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
new THREE.DirectionalLight(0xffffff, 1.5);
directionalLight.position.set(10, 20, 10); directionalLight.position.set(10, 20, 10);
scene.add(directionalLight); scene.add(directionalLight);
// ========================================================
// Reticle // Reticle
// ========================================================
const loader = new GLTFLoader(); const loader = new GLTFLoader();
loader.load( loader.load(
"https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf", "https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf",
(gltf) => { (gltf) => {
reticle = gltf.scene; reticle = gltf.scene;
reticle.visible = false; reticle.visible = false;
scene.add(reticle); scene.add(reticle);
}, },
undefined, undefined,
(error) => console.error("Fehler beim Laden des Reticles:", error)
(error) => {
console.error("Fehler beim Laden des Reticles:", error);
},
); );
// ======================================================== // WebXR session
// Start WebXR AR session
// ========================================================
currentSession = await navigator.xr.requestSession("immersive-ar", { currentSession = await navigator.xr.requestSession("immersive-ar", {
optionalFeatures: ["dom-overlay"],
domOverlay: {
root: document.body,
},
requiredFeatures: ["hit-test"], requiredFeatures: ["hit-test"],
optionalFeatures: ["dom-overlay"],
domOverlay: { root: document.body },
}); });
// Let Three.js manage the XR render state / framebuffer. currentSession.updateRenderState({
await renderer.xr.setSession(currentSession); baseLayer: new XRWebGLLayer(currentSession, gl),
});
const referenceSpace = renderer.xr.getReferenceSpace();
if (!referenceSpace) {
throw new Error("XR reference space konnte nicht erstellt werden.");
}
const viewerSpace =
await currentSession.requestReferenceSpace("viewer");
const hitTestSource =
await currentSession.requestHitTestSource({
space: viewerSpace,
});
// ======================================================== const referenceSpace = await currentSession.requestReferenceSpace("local");
// Show main menu const viewerSpace = await currentSession.requestReferenceSpace("viewer");
// ======================================================== const hitTestSource = await currentSession.requestHitTestSource({
space: viewerSpace,
});
document.getElementById("menu-bar").style.display = "flex"; document.getElementById("menu-bar").style.display = "flex";
// ========================================================
// AR session ended
// Reload the complete website
// ========================================================
currentSession.addEventListener("end", () => { currentSession.addEventListener("end", () => {
console.log("AR session ended"); console.log("AR session ended");
// Completely reload the website.
// This resets the AR canvas, menus, scene, map,
// variables, and all other application state.
window.location.reload(); window.location.reload();
}); });
// ========================================================
// Select objects in AR
// ========================================================
canvas.addEventListener("pointerdown", selectModelFromScene); canvas.addEventListener("pointerdown", selectModelFromScene);
// ========================================================
// Geolocation // Geolocation
// ========================================================
if (navigator.geolocation) { if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
(position) => { (position) => {
...@@ -1256,125 +1211,107 @@ async function activateXR(sceneData = null) { ...@@ -1256,125 +1211,107 @@ async function activateXR(sceneData = null) {
longitude: window.roundTo(position.coords.longitude, 5), longitude: window.roundTo(position.coords.longitude, 5),
}; };
console.log( console.log("GeoLocation: " + JSON.stringify(geoLocation));
"GeoLocation: " + JSON.stringify(geoLocation)
);
// =================================================
// Load saved scene models
// =================================================
if (sceneData && Array.isArray(sceneData.models)) { if (sceneData && Array.isArray(sceneData.models)) {
sceneData.models.forEach((model) => { sceneData.models.forEach((model) => {
if (model.name) { if (!model.name) return;
const modelDefinition =
Object.values(models).find(
(m) => model.name === m.name
);
if (!modelDefinition) { const modelDefinition = Object.values(models).find(
console.error( (m) => model.name === m.name
"Modell nicht gefunden:", );
model.name
);
return;
}
const filePath = modelDefinition.file; if (!modelDefinition) {
console.error("Modell nicht gefunden:", model.name);
return;
}
// ar_overviewmap.js is loaded before user interaction, const { x, z } = window.leafletToThree(model.lat, model.lng);
// and exposes this conversion function on window. const positionVector = new THREE.Vector3(
const coordinates = x,
window.leafletToThree(model.lat, model.lng); model.position?.y ?? 0,
z
);
const positionVector = placeModel(modelDefinition.file, positionVector, (placed) => {
new THREE.Vector3( if (model.rotation) {
coordinates.x, placed.rotation.set(
model.position.y, model.rotation._x ?? model.rotation.x ?? 0,
coordinates.z model.rotation._y ?? model.rotation.y ?? 0,
model.rotation._z ?? model.rotation.z ?? 0
); );
}
placeModel( if (model.scale) {
filePath, placed.scale.set(
positionVector, model.scale.x,
(placed) => { model.scale.y,
if (model.rotation) { model.scale.z
placed.rotation.set( );
model.rotation._x ?? model.rotation.x ?? 0, }
model.rotation._y ?? model.rotation.y ?? 0, });
model.rotation._z ?? model.rotation.z ?? 0
);
}
if (model.scale) {
placed.scale.set(
model.scale.x,
model.scale.y,
model.scale.z
);
}
}
);
}
}); });
} }
}, },
(error) => { (error) => {
console.error( console.error("Fehler bei der Geolokalisierung:", error);
"Fehler bei der Geolokalisierung:",
JSON.stringify(error),
);
}, },
{ {
enableHighAccuracy: true, enableHighAccuracy: true,
maximumAge: 2000, maximumAge: 2000,
timeout: 5000, timeout: 5000,
}, }
); );
} }
// ======================================================== // Keep the original explicit XR frame loop.
// Modern Three.js XR render loop currentSession.requestAnimationFrame(function onXRFrame(time, frame) {
// ======================================================== currentSession.requestAnimationFrame(onXRFrame);
renderer.setAnimationLoop((time, frame) => { const session = frame.session;
if (!frame) { const baseLayer = session.renderState.baseLayer;
return;
} if (!baseLayer) return;
// ====================================================== gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);
// Hit testing
// ======================================================
const hitTestResults = const pose = frame.getViewerPose(referenceSpace);
frame.getHitTestResults(hitTestSource); if (!pose) return;
// This application uses one camera/view, as in the original version.
const view = pose.views[0];
const viewport = baseLayer.getViewport(view);
if (!viewport) return;
renderer.setViewport(
viewport.x,
viewport.y,
viewport.width,
viewport.height
);
camera.matrix.fromArray(view.transform.matrix);
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0) { if (hitTestResults.length > 0) {
const hitPose = const hitPose = hitTestResults[0].getPose(referenceSpace);
hitTestResults[0].getPose(referenceSpace);
if (hitPose && reticle) { if (hitPose && reticle) {
reticle.visible = true; reticle.visible = true;
reticle.position.set( reticle.position.set(
hitPose.transform.position.x, hitPose.transform.position.x,
hitPose.transform.position.y, hitPose.transform.position.y,
hitPose.transform.position.z, hitPose.transform.position.z
); );
reticle.updateMatrixWorld(true); reticle.updateMatrixWorld(true);
} }
} else if (reticle) { } else if (reticle) {
reticle.visible = false; reticle.visible = false;
} }
// ======================================================
// Render AR scene
// ======================================================
renderer.render(scene, camera); renderer.render(scene, camera);
}); });
} }
...@@ -1424,7 +1361,6 @@ window.updateScale = updateScale; ...@@ -1424,7 +1361,6 @@ window.updateScale = updateScale;
window.updateMoveDelta = updateMoveDelta; window.updateMoveDelta = updateMoveDelta;
window.moveModelDynamic = moveModelDynamic; window.moveModelDynamic = moveModelDynamic;
window.closeDynamicMenu = closeDynamicMenu; window.closeDynamicMenu = closeDynamicMenu;
window.roundTo = window.roundTo;
/* ============================================================ /* ============================================================
GLOBAL API BRIDGE GLOBAL API BRIDGE
...@@ -1446,7 +1382,5 @@ window.confirmExit = confirmExit; ...@@ -1446,7 +1382,5 @@ window.confirmExit = confirmExit;
window.closeInfoDialog = closeInfoDialog; window.closeInfoDialog = closeInfoDialog;
window.getAllPlacedModels = getAllPlacedModels; window.getAllPlacedModels = getAllPlacedModels;
window.activateXR = activateXR; window.activateXR = activateXR;
window.getXRRenderCamera = () => window.getXRRenderCamera = () => camera;
xrRenderer && xrRenderer.xr.isPresenting window.getGeoLocation = () => geoLocation;
? xrRenderer.xr.getCamera(camera)
: camera;
import { activateXR } from './ar_main.js';
import { loadSceneFromFile } from './ar_download.js';
/* ========================= */ /* ========================= */
/* DEBUGGING UND START */ /* DEBUGGING UND START */
/* ========================= */ /* ========================= */
......
...@@ -306,7 +306,7 @@ ...@@ -306,7 +306,7 @@
============================================================ --> ============================================================ -->
<div id="app-version"> <div id="app-version">
v186.0.1 v186.0.2
</div> </div>
...@@ -317,18 +317,18 @@ ...@@ -317,18 +317,18 @@
<!-- Debug console loads first so it can capture module errors/logs --> <!-- Debug console loads first so it can capture module errors/logs -->
<script src="ar_debug_console.js"></script> <script src="ar_debug_console.js"></script>
<!-- Application modules -->
<script type="module" src="ar_main.js"></script>
<script type="module" src="ar_overviewmap.js"></script>
<script type="module" src="ar_download.js"></script>
<script type="module" src="ar_start.js"></script>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://unpkg.com/leaflet/dist/leaflet.css" /> href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<!-- Application modules -->
<script type="module" src="ar_main.js"></script>
<script type="module" src="ar_overviewmap.js"></script>
<script type="module" src="ar_download.js"></script>
<script type="module" src="ar_start.js"></script>
......
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