Implement model optimization and caching for 3D characters
- Added a new modelsProxyRouter to handle requests for optimized 3D character models. - Introduced modelsProxyService to manage GLB file optimization using gltf-transform with Draco compression. - Updated app.js to include the new modelsProxyRouter for API access. - Enhanced .gitignore to exclude model cache files. - Added scripts for optimizing GLB models and updated README with optimization instructions. - Integrated DRACOLoader in Character3D.vue for loading compressed models. - Updated FamilyView.vue to streamline character rendering logic.
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
import { markRaw } from 'vue';
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
|
||||
import { getApiBaseURL } from '@/utils/axios.js';
|
||||
|
||||
export default {
|
||||
name: 'Character3D',
|
||||
@@ -76,12 +78,9 @@ export default {
|
||||
modelPath() {
|
||||
const gender = this.actualGender;
|
||||
const ageGroup = this.ageGroup;
|
||||
|
||||
// Versuche zuerst altersspezifisches Modell
|
||||
const specificModel = `/models/3d/falukant/characters/${gender}_${ageGroup}.glb`;
|
||||
|
||||
// Fallback auf Basis-Modell
|
||||
return specificModel;
|
||||
const base = getApiBaseURL();
|
||||
const prefix = base ? `${base}/api/models/3d/falukant/characters` : '/api/models/3d/falukant/characters';
|
||||
return `${prefix}/${gender}_${ageGroup}.glb`;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -150,8 +149,8 @@ export default {
|
||||
},
|
||||
|
||||
loadBackground() {
|
||||
// Zufällig einen Hintergrund auswählen
|
||||
const backgrounds = ['bg1.png', 'bg2.png'];
|
||||
// Optimierte Versionen (512×341, ~130 KB); Originale ~3 MB
|
||||
const backgrounds = ['bg1_opt.png', 'bg2_opt.png'];
|
||||
const randomBg = backgrounds[Math.floor(Math.random() * backgrounds.length)];
|
||||
const bgPath = `/images/falukant/backgrounds/${randomBg}`;
|
||||
|
||||
@@ -200,18 +199,24 @@ export default {
|
||||
}
|
||||
|
||||
try {
|
||||
const dracoLoader = new DRACOLoader();
|
||||
dracoLoader.setDecoderPath('/draco/gltf/');
|
||||
const loader = new GLTFLoader();
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
const modelPath = this.modelPath;
|
||||
|
||||
// Versuche zuerst spezifisches Modell, dann Fallback
|
||||
const base = getApiBaseURL();
|
||||
const prefix = base ? `${base}/api/models/3d/falukant/characters` : '/api/models/3d/falukant/characters';
|
||||
const fallbackPath = `${prefix}/${this.actualGender}.glb`;
|
||||
|
||||
let gltf;
|
||||
try {
|
||||
gltf = await loader.loadAsync(modelPath);
|
||||
} catch (error) {
|
||||
console.warn(`Could not load ${modelPath}, trying fallback model`);
|
||||
// Fallback auf Basis-Modell
|
||||
const fallbackPath = `/models/3d/falukant/characters/${this.actualGender}.glb`;
|
||||
gltf = await loader.loadAsync(fallbackPath);
|
||||
} finally {
|
||||
dracoLoader.dispose();
|
||||
}
|
||||
|
||||
// Modell als raw markieren, um Vue's Reactivity zu vermeiden
|
||||
|
||||
@@ -48,3 +48,4 @@ apiClient.interceptors.response.use(response => {
|
||||
});
|
||||
|
||||
export default apiClient;
|
||||
export { getApiBaseURL };
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
<div class="contenthidden">
|
||||
<StatusBar />
|
||||
<div class="contentscroll family-layout">
|
||||
<!-- 3D-Modell für man selbst links -->
|
||||
<div class="self-character-3d" v-if="ownCharacter">
|
||||
<Character3D
|
||||
:gender="ownCharacter.gender"
|
||||
:age="ownCharacter.age"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="family-content">
|
||||
<h2>{{ $t('falukant.family.title') }}</h2>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user