diff --git a/frontend/scripts/optimize-glb.mjs b/frontend/scripts/optimize-glb.mjs index c862b11..ae7c0c5 100755 --- a/frontend/scripts/optimize-glb.mjs +++ b/frontend/scripts/optimize-glb.mjs @@ -1,12 +1,13 @@ #!/usr/bin/env node /** - * Optimiert alle Falukant-Charakter-GLBs mit Draco + Textur-Optimierung. + * Optimiert Falukant-Charakter- und Haus-GLBs mit Draco + Textur-Optimierung. * Ausgabe: *_opt.glb im selben Verzeichnis. * Voraussetzung: npm install (@gltf-transform/cli als Dev-Dep) * * Aufruf: npm run optimize-models * Optional können MODEL_SOURCE_DIR und MODEL_OUTPUT_DIR gesetzt werden, um - * Modelle aus dem separaten YourPart3Assets-Repository zu verarbeiten. + * genau einen Modellordner aus dem separaten YourPart3Assets-Repository zu + * verarbeiten. */ import fs from 'fs'; @@ -15,24 +16,22 @@ import { fileURLToPath } from 'url'; import path from 'path'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const defaultSourceDir = path.join(__dirname, '..', 'models-src', '3d', 'falukant', 'characters'); -const defaultOutputDir = path.join(__dirname, '..', 'public', 'models', '3d', 'falukant', 'characters'); -const sourceDir = path.resolve(process.env.MODEL_SOURCE_DIR || defaultSourceDir); -const outputDir = path.resolve(process.env.MODEL_OUTPUT_DIR || defaultOutputDir); +const modelsRoot = path.join(__dirname, '..', 'models-src', '3d', 'falukant'); +const publicModelsRoot = path.join(__dirname, '..', 'public', 'models', '3d', 'falukant'); const cli = path.join(__dirname, '..', 'node_modules', '.bin', 'gltf-transform'); -function listSourceModels() { +function listSourceModels(sourceDir) { return fs.readdirSync(sourceDir) .filter((file) => file.endsWith('.glb')) .filter((file) => !file.endsWith('_opt.glb')) .sort((a, b) => a.localeCompare(b)); } -function ensureOutputDir() { +function ensureOutputDir(outputDir) { fs.mkdirSync(outputDir, { recursive: true }); } -function removeStaleOptimizedModels() { +function removeStaleOptimizedModels(outputDir) { if (!fs.existsSync(outputDir)) { return; } @@ -43,43 +42,74 @@ function removeStaleOptimizedModels() { } } -console.log('Optimize Falukant character GLBs (Draco + texture 1024)\n'); - -if (!fs.existsSync(sourceDir)) { - console.error(`Source directory not found: ${sourceDir}`); - process.exit(1); -} - -ensureOutputDir(); -removeStaleOptimizedModels(); - -const models = listSourceModels(); -if (models.length === 0) { - console.log('No source GLBs found.'); - process.exit(0); -} - -for (const f of models) { - const input = path.join(sourceDir, f); - const out = f.replace(/\.glb$/, '_opt.glb'); - const output = path.join(outputDir, out); - - try { - const result = spawnSync( - 'node', - [cli, 'optimize', input, output, '--compress', 'draco', '--texture-size', '1024'], - { - stdio: 'inherit', - cwd: path.join(__dirname, '..'), - } - ); - if (result.status !== 0) { - throw new Error(`gltf-transform exited with ${result.status}`); +function optimizeModelDirectory({ name, sourceDir, outputDir, required = false }) { + if (!fs.existsSync(sourceDir)) { + if (required) { + console.error(`Source directory not found: ${sourceDir}`); + process.exitCode = 1; + } + return; + } + + ensureOutputDir(outputDir); + removeStaleOptimizedModels(outputDir); + + const models = listSourceModels(sourceDir); + if (models.length === 0) { + console.log(`No ${name} GLBs found.`); + return; + } + + console.log(`Optimize Falukant ${name} GLBs (Draco + texture 1024)\n`); + + for (const f of models) { + const input = path.join(sourceDir, f); + const out = f.replace(/\.glb$/, '_opt.glb'); + const output = path.join(outputDir, out); + + try { + const result = spawnSync( + 'node', + [cli, 'optimize', input, output, '--compress', 'draco', '--texture-size', '1024'], + { + stdio: 'inherit', + cwd: path.join(__dirname, '..'), + } + ); + if (result.status !== 0) { + throw new Error(`gltf-transform exited with ${result.status}`); + } + } catch (e) { + console.error(`Failed: ${f}`); + process.exitCode = 1; } - } catch (e) { - console.error(`Failed: ${f}`); - process.exitCode = 1; } } -console.log(`\nDone. Optimized models written to ${outputDir}`); +const customSourceDir = process.env.MODEL_SOURCE_DIR; +const customOutputDir = process.env.MODEL_OUTPUT_DIR; +if (Boolean(customSourceDir) !== Boolean(customOutputDir)) { + console.error('MODEL_SOURCE_DIR and MODEL_OUTPUT_DIR must be set together.'); + process.exit(1); +} + +if (customSourceDir) { + optimizeModelDirectory({ + name: 'custom', + sourceDir: path.resolve(customSourceDir), + outputDir: path.resolve(customOutputDir), + required: true, + }); +} else { + optimizeModelDirectory({ + name: 'character', + sourceDir: path.join(modelsRoot, 'characters'), + outputDir: path.join(publicModelsRoot, 'characters'), + required: true, + }); + optimizeModelDirectory({ + name: 'house', + sourceDir: path.join(modelsRoot, 'houses'), + outputDir: path.join(publicModelsRoot, 'houses'), + }); +} diff --git a/frontend/src/components/falukant/House3D.vue b/frontend/src/components/falukant/House3D.vue new file mode 100644 index 0000000..fcd8f24 --- /dev/null +++ b/frontend/src/components/falukant/House3D.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/frontend/src/utils/falukantHouseModels.js b/frontend/src/utils/falukantHouseModels.js new file mode 100644 index 0000000..10ef3e7 --- /dev/null +++ b/frontend/src/utils/falukantHouseModels.js @@ -0,0 +1,15 @@ +const HOUSE_MODELS = Object.freeze({ + 'Unter der Brücke': 'under_bridge', + 'Strohhütte': 'straw_hut', + Holzhaus: 'wooden_house', + Hinterhofzimmer: 'backyard_room', + 'Kleines Familienhaus': 'family_house', + Stadthaus: 'townhouse', + Villa: 'villa', + Herrenhaus: 'mansion', + Schloss: 'castle', +}); + +export function getFalukantHouseModel(houseType) { + return HOUSE_MODELS[houseType?.labelTr] || 'under_bridge'; +} diff --git a/frontend/src/views/falukant/HouseView.vue b/frontend/src/views/falukant/HouseView.vue index 722c2e0..ac765d9 100755 --- a/frontend/src/views/falukant/HouseView.vue +++ b/frontend/src/views/falukant/HouseView.vue @@ -19,7 +19,12 @@

-
+

{{ $t('falukant.house.statusreport') }}

@@ -128,8 +133,12 @@

{{ $t('falukant.house.buyablehouses') }}

-
+

{{ $t(`falukant.house.type.${house.houseType.labelTr}`) }}

@@ -155,13 +164,15 @@