Add tank catalog with USDZ models and tank selection

Introduce TankDefinition/TankCatalog loaded from Tanks.json, bundle the
Drachengas USDZ tank models, add tank selection and preview views, and
update the AR experience, editor and project views to use the catalog.
Includes tests for catalog loading and model selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-26 19:12:39 +02:00
parent 992bb32025
commit b8536d4182
63 changed files with 2317 additions and 188 deletions

View File

@ -7,40 +7,30 @@
import Foundation
/// Verfügbare Tankgrößen laut Projektplan Phase 4 (Modell + korrekter Maßstab).
enum TankSize: String, CaseIterable, Identifiable, Codable, Hashable {
/// Verfügbare Tankgrößen. Die Enum-Fälle sind reine, stabile Identitäten
/// (werden so persistiert). Anzeigenamen und 3D-Modelle liefert der
/// `TankCatalog` (aus `Tanks.json`) – siehe `TankDefinition`.
nonisolated enum TankSize: String, CaseIterable, Identifiable, Codable, Hashable {
case t1_2
case t2_1
case t2_9
var id: String { rawValue }
var displayName: String {
switch self {
case .t1_2: "1,2 t"
case .t2_1: "2,1 t"
case .t2_9: "2,9 t"
}
}
}
/// Verfügbare Tankfarben (Farbvariante mit Logo).
enum TankColor: String, CaseIterable, Identifiable, Codable, Hashable {
/// Verfügbare Tankfarben. Welche Farben tatsächlich auswählbar sind, ergibt
/// sich dynamisch aus dem `TankCatalog` (abhängig von Größe & Aufstellungsart).
nonisolated enum TankColor: String, CaseIterable, Identifiable, Codable, Hashable {
case white
case green
case olive
var id: String { rawValue }
var displayName: String {
switch self {
case .white: "Weiß"
case .green: "Grün"
}
}
}
/// Aufstellungsart des Tanks.
enum TankPlacement: String, CaseIterable, Identifiable, Codable, Hashable {
/// Aufstellungsart des Tanks. Steuert neben der Modellauswahl auch das
/// AR-Verhalten (Grube, Occlusion, „nur Deckel").
nonisolated enum TankPlacement: String, CaseIterable, Identifiable, Codable, Hashable {
case aboveGround
case belowGround
@ -62,19 +52,14 @@ enum TankPlacement: String, CaseIterable, Identifiable, Codable, Hashable {
}
}
/// Ein für ein Projekt ausgewählter Tank. Kombiniert die in Phase 4 des
/// Projektplans vorgesehenen Auswahlmöglichkeiten: Größe, Farbe und
/// Aufstellungsart sowie die optionale halbtransparente Darstellung.
struct Tank: Hashable, Codable {
/// Die für ein Projekt getroffene Tank-Auswahl. `Tank` ist die persistierte
/// Identität (Größe, Farbe, Aufstellungsart); die zugehörigen Anzeigenamen und
/// das 3D-Modell werden über den `TankCatalog` aufgelöst.
nonisolated struct Tank: Hashable, Codable {
var size: TankSize = .t1_2
var color: TankColor = .white
var placement: TankPlacement = .aboveGround
/// Optionale Darstellung, bei der nur der Deckel sichtbar ist.
var showLidOnly: Bool = false
/// Kurzbeschreibung für Listen und Detailanzeigen.
var displayName: String {
"\(size.displayName) · \(color.displayName) · \(placement.displayName)"
}
}