Files
Gas-Tank-AR-App/GasTankAR/Views/TankAR/TankHighlightFactory.swift
2026-09-02 20:54:36 +02:00

70 lines
2.6 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// TankHighlightFactory.swift
// GasTankAR
//
// Created by Dennis Nemec on 28.08.26.
//
import RealityKit
import UIKit
/// Baut die Auswahl-Markierung um den Tank: ein (ansonsten unsichtbarer) Quader, dessen
/// acht Ecken mit kräftig gefärbten Winkeln hervorgehoben werden – deutlich sichtbar,
/// ohne den Tank selbst zu verdecken.
@MainActor
enum TankHighlightFactory {
/// Name der Markierungs-Entity (zum Ein-/Ausblenden bei Auswahl).
static let name = "TankSelectionHighlight"
private static let color = UIColor.systemTeal
/// Erzeugt die Eck-Winkel passend zur Bounding-Box (im Koordinatensystem des Containers).
static func makeHighlight(for bounds: BoundingBox) -> Entity {
let root = Entity()
root.name = name
let extents = bounds.extents
let smallestEdge = min(extents.x, min(extents.y, extents.z))
let armLength = max(0.05, smallestEdge * 0.3)
let thickness = max(0.008, smallestEdge * 0.05)
var material = UnlitMaterial(color: color)
material.faceCulling = .none
for x in [bounds.min.x, bounds.max.x] {
for y in [bounds.min.y, bounds.max.y] {
for z in [bounds.min.z, bounds.max.z] {
let corner = SIMD3(x, y, z)
// Vorzeichen: Winkel zeigt von der Ecke nach innen (zur Boxmitte).
let signX: Float = (x == bounds.min.x) ? 1 : -1
let signY: Float = (y == bounds.min.y) ? 1 : -1
let signZ: Float = (z == bounds.min.z) ? 1 : -1
root.addChild(beam(
size: SIMD3(armLength, thickness, thickness),
center: corner + SIMD3(signX * armLength / 2, 0, 0),
material: material
))
root.addChild(beam(
size: SIMD3(thickness, armLength, thickness),
center: corner + SIMD3(0, signY * armLength / 2, 0),
material: material
))
root.addChild(beam(
size: SIMD3(thickness, thickness, armLength),
center: corner + SIMD3(0, 0, signZ * armLength / 2),
material: material
))
}
}
}
return root
}
private static func beam(size: SIMD3<Float>, center: SIMD3<Float>, material: UnlitMaterial) -> ModelEntity {
let beam = ModelEntity(mesh: .generateBox(size: size), materials: [material])
beam.position = center
return beam
}
}