diff --git a/public/index.html b/public/index.html index c3af7690805c5a7ab7c2191c266b10cabbe90389..b8880da3f34062d10700be89d1a052ccbf28dfd9 100644 --- a/public/index.html +++ b/public/index.html @@ -80,7 +80,6 @@ } </style> <script src="https://unpkg.com/three@0.126.0/build/three.js"></script> - <script src="https://unpkg.com/three-mesh-ui@6.4.1/build/three-mesh-ui.js"></script> <script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script> </head> <body> @@ -114,27 +113,6 @@ scene.add(reticle); }); -const container = new ThreeMeshUI.Block({ - width: 1.2, - height: 0.7, - padding: 0.2, - fontFamily: './assets/Roboto-msdf.json', - fontTexture: './assets/Roboto-msdf.png', -}); - -// - -const text = new ThreeMeshUI.Text({ - content: "Some text to be displayed" -}); - -container.add( text ); - -// scene is a THREE.Scene (see three.js) -scene.add( container ); - -// This is typically done in the render loop : -ThreeMeshUI.update(); // Modelle laden loader.load("https://threejs.org/examples/models/gltf/RobotExpressive/RobotExpressive.glb", (gltf) => { models.car = gltf.scene; @@ -143,7 +121,32 @@ ThreeMeshUI.update(); models.lamp = gltf.scene; }); - + // 3D-Menü erstellen + const menuGeometry = new THREE.PlaneGeometry(0.5, 0.2); // Menügröße + const menuMaterial = new THREE.MeshBasicMaterial({ color: 0x333333, opacity: 0.8, transparent: true }); + menu = new THREE.Mesh(menuGeometry, menuMaterial); + menu.position.set(0, -0.5, -1); // Unten im Kamerasichtfeld + scene.add(menu); + + // Menü-Buttons als Flächen + const buttonGeometry = new THREE.PlaneGeometry(0.15, 0.1); + const buttonMaterial1 = new THREE.MeshBasicMaterial({ color: 0x2196F3 }); + const buttonMaterial2 = new THREE.MeshBasicMaterial({ color: 0xFF9800 }); + + const carButton = new THREE.Mesh(buttonGeometry, buttonMaterial1); + carButton.position.set(-0.2, -0.5, -0.99); // Links unten + scene.add(carButton); + + const lampButton = new THREE.Mesh(buttonGeometry, buttonMaterial2); + lampButton.position.set(0.2, -0.5, -0.99); // Rechts unten + scene.add(lampButton); + + + + // Raycaster für Button-Interaktion + const raycaster = new THREE.Raycaster(); + const pointer = new THREE.Vector2(); + // AR-Session starten const session = await navigator.xr.requestSession('immersive-ar', { requiredFeatures: ['hit-test'] }); session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) }); @@ -156,6 +159,31 @@ ThreeMeshUI.update(); session.addEventListener("select", (event) => { if (!reticle) return; + // Raycaster von der Kameraposition (Mitte des Bildschirms) + raycaster.setFromCamera(pointer, camera); + const intersects = raycaster.intersectObjects([carButton, lampButton]); + + // Prüfen, ob ein Button getroffen wurde + if (intersects.length > 0) { + const clickedButton = intersects[0].object; + + if (clickedButton === carButton) { + selectedModel = 'car'; + console.log('Auto ausgewählt'); + } else if (clickedButton === lampButton) { + selectedModel = 'lamp'; + console.log('Laterne ausgewählt'); + } + } + // Kein Button getroffen -> Modell platzieren + else if (models[selectedModel]) { + const clone = models[selectedModel].clone(); + clone.position.copy(reticle.position); + clone.scale.set(0.5, 0.5, 0.5); // Größe anpassen + scene.add(clone); + console.log(`${selectedModel} platziert`); + } + }); // AR-Rendering function onXRFrame(time, frame) {