import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { RequirementMapping, SceneParams, SceneTemplate, LightingParams, EnvironmentParams, CompositionParams, StyleParams, MappingResult } from '../models/requirement-mapping.interface'; import { AtmospherePreviewService } from './atmosphere-preview.service'; @Injectable({ providedIn: 'root' }) export class SceneGenerationService { // 场景模板配置 private sceneTemplates: Map = new Map(); constructor(private atmospherePreviewService: AtmospherePreviewService) { this.initializeSceneTemplates(); } /** * 根据分析结果生成场景参数和预览图 */ generateSceneFromAnalysis(analysisResult: any, sceneType: SceneTemplate): Observable { const baseParams = this.getSceneTemplate(sceneType); const adaptedParams = this.adaptParamsFromAnalysis(baseParams, analysisResult); // 生成氛围感预览图 return this.atmospherePreviewService.generateAtmospherePreview(adaptedParams, sceneType).pipe( map(previewResult => { const confidence = this.calculateConfidence(analysisResult, adaptedParams); const suggestions = this.generateSuggestions(analysisResult, adaptedParams); return { success: true, sceneId: this.generateSceneId(sceneType), generatedParams: adaptedParams, previewUrl: previewResult.url, confidence, suggestions, metadata: { generatedAt: new Date(), analysisVersion: '1.0', processingTime: previewResult.metadata.processingTime } }; }) ); } /** * 获取场景模板 */ getSceneTemplate(sceneType: SceneTemplate): SceneParams { return this.sceneTemplates.get(sceneType) || this.getDefaultSceneParams(); } /** * 获取所有可用的场景模板 */ getAvailableScenes(): Array<{template: SceneTemplate, name: string, description: string}> { return [ { template: SceneTemplate.LIVING_ROOM_MODERN, name: '现代客厅', description: '简约现代风格的客厅空间' }, { template: SceneTemplate.LIVING_ROOM_CLASSIC, name: '经典客厅', description: '传统经典风格的客厅空间' }, { template: SceneTemplate.BEDROOM_MINIMAL, name: '简约卧室', description: '极简主义风格的卧室空间' }, { template: SceneTemplate.BEDROOM_COZY, name: '温馨卧室', description: '温馨舒适的卧室空间' }, { template: SceneTemplate.KITCHEN_CONTEMPORARY, name: '现代厨房', description: '当代风格的厨房空间' }, { template: SceneTemplate.KITCHEN_TRADITIONAL, name: '传统厨房', description: '传统风格的厨房空间' }, { template: SceneTemplate.BATHROOM_LUXURY, name: '豪华浴室', description: '奢华风格的浴室空间' }, { template: SceneTemplate.BATHROOM_MINIMAL, name: '简约浴室', description: '简约风格的浴室空间' }, { template: SceneTemplate.OFFICE_MODERN, name: '现代办公室', description: '现代化的办公空间' }, { template: SceneTemplate.OFFICE_TRADITIONAL, name: '传统办公室', description: '传统风格的办公空间' }, { template: SceneTemplate.DINING_FORMAL, name: '正式餐厅', description: '正式的用餐空间' }, { template: SceneTemplate.DINING_CASUAL, name: '休闲餐厅', description: '休闲的用餐空间' }, { template: SceneTemplate.STUDIO_APARTMENT, name: '工作室公寓', description: '开放式的工作室公寓' }, { template: SceneTemplate.OUTDOOR_PATIO, name: '户外露台', description: '户外露台空间' }, { template: SceneTemplate.OUTDOOR_GARDEN, name: '花园景观', description: '花园景观空间' } ]; } /** * 根据分析结果适配场景参数 */ private adaptParamsFromAnalysis(baseParams: SceneParams, analysisResult: any): SceneParams { const adaptedParams = JSON.parse(JSON.stringify(baseParams)); // 深拷贝 // 适配灯光参数 if (analysisResult.lightingAnalysis) { adaptedParams.lighting = this.adaptLightingParams( adaptedParams.lighting, analysisResult.lightingAnalysis ); } // 适配环境参数 if (analysisResult.enhancedColorAnalysis || analysisResult.textureAnalysis) { adaptedParams.environment = this.adaptEnvironmentParams( adaptedParams.environment, analysisResult ); } // 适配风格参数 if (analysisResult.formAnalysis || analysisResult.patternAnalysis) { adaptedParams.style = this.adaptStyleParams( adaptedParams.style, analysisResult ); } return adaptedParams; } /** * 适配灯光参数 */ private adaptLightingParams(baseParams: LightingParams, lightingAnalysis: any): LightingParams { const adapted = { ...baseParams }; // 主光源适配 if (lightingAnalysis.lightSourceIdentification) { const primarySource = lightingAnalysis.lightSourceIdentification.primarySources?.[0]; if (primarySource) { adapted.primaryLight.type = primarySource.type || adapted.primaryLight.type; adapted.primaryLight.intensity = primarySource.intensity || adapted.primaryLight.intensity; adapted.primaryLight.direction = primarySource.position?.direction || adapted.primaryLight.direction; } // 色温适配 if (lightingAnalysis.illuminationAnalysis?.colorTemperature) { adapted.primaryLight.temperature = lightingAnalysis.illuminationAnalysis.colorTemperature.kelvin || adapted.primaryLight.temperature; } } // 环境光适配 if (lightingAnalysis.ambientAnalysis) { adapted.ambientLight.strength = lightingAnalysis.ambientAnalysis.ambientLevel?.strength || adapted.ambientLight.strength; adapted.ambientLight.mood = lightingAnalysis.ambientAnalysis.lightingMood?.primary || adapted.ambientLight.mood; } // 阴影适配 if (lightingAnalysis.shadowAnalysis) { adapted.shadows.intensity = lightingAnalysis.shadowAnalysis.shadowPresence?.intensity || adapted.shadows.intensity; const sharpnessMap: {[key: string]: number} = { 'very-soft': 20, 'soft': 40, 'medium': 60, 'sharp': 80, 'very-sharp': 100 }; const sharpness = lightingAnalysis.shadowAnalysis.shadowPresence?.sharpness; adapted.shadows.softness = 100 - (sharpnessMap[sharpness] || 60); } return adapted; } /** * 适配环境参数 */ private adaptEnvironmentParams(baseParams: EnvironmentParams, analysisResult: any): EnvironmentParams { const adapted = { ...baseParams }; // 根据色彩分析适配氛围 if (analysisResult.enhancedColorAnalysis?.colorPsychology) { const mood = analysisResult.enhancedColorAnalysis.colorPsychology.primaryMood; const atmosphereMap: {[key: string]: string} = { 'calm': 'minimal', 'energetic': 'modern', 'warm': 'cozy', 'sophisticated': 'luxurious', 'natural': 'natural', 'modern': 'modern' }; adapted.atmosphere = atmosphereMap[mood] as any || adapted.atmosphere; } // 根据材质分析适配设置 if (analysisResult.textureAnalysis?.materialClassification) { const primaryMaterial = analysisResult.textureAnalysis.materialClassification.primaryMaterial?.category; if (primaryMaterial === 'wood' || primaryMaterial === 'fabric') { adapted.setting = 'indoor'; } else if (primaryMaterial === 'stone' || primaryMaterial === 'metal') { adapted.setting = adapted.setting === 'outdoor' ? 'outdoor' : 'indoor'; } } return adapted; } /** * 适配风格参数 */ private adaptStyleParams(baseParams: StyleParams, analysisResult: any): StyleParams { const adapted = { ...baseParams }; // 根据形体分析适配渲染风格 if (analysisResult.formAnalysis?.overallAssessment) { const complexity = analysisResult.formAnalysis.overallAssessment.formComplexity; if (complexity > 70) { adapted.renderStyle = 'dramatic'; adapted.textureDetail = 'high'; } else if (complexity < 30) { adapted.renderStyle = 'minimalist'; adapted.textureDetail = 'medium'; } } // 根据纹理分析适配纹理细节 if (analysisResult.patternAnalysis?.patternRecognition) { const patternCount = analysisResult.patternAnalysis.patternRecognition.primaryPatterns?.length || 0; if (patternCount > 2) { adapted.textureDetail = 'high'; } else if (patternCount === 0) { adapted.textureDetail = 'low'; } } // 根据色彩分析适配色彩分级 if (analysisResult.enhancedColorAnalysis) { const saturation = analysisResult.enhancedColorAnalysis.colorWheel?.saturation; if (saturation > 70) { adapted.colorGrading = 'high-contrast'; } else if (saturation < 30) { adapted.colorGrading = 'vintage'; } } return adapted; } /** * 生成氛围感预览图URL */ /** * 生成氛围感预览图URL(已弃用,使用 AtmospherePreviewService) * @deprecated 使用 AtmospherePreviewService.generateAtmospherePreview 替代 */ private generateAtmospherePreview(params: SceneParams, sceneType: SceneTemplate): string { // 这里应该调用实际的预览图生成服务 // 目前返回模拟的URL const baseUrl = '/assets/previews/'; const sceneId = sceneType.toString(); const styleHash = this.generateStyleHash(params); return `${baseUrl}${sceneId}_${styleHash}.jpg`; } /** * 生成场景ID */ private generateSceneId(sceneType: SceneTemplate): string { const timestamp = Date.now(); return `${sceneType}_${timestamp}`; } /** * 计算映射置信度 */ private calculateConfidence(analysisResult: any, params: SceneParams): number { let confidence = 50; // 基础置信度 // 根据分析结果的完整性调整置信度 if (analysisResult.lightingAnalysis) confidence += 15; if (analysisResult.enhancedColorAnalysis) confidence += 15; if (analysisResult.textureAnalysis) confidence += 10; if (analysisResult.formAnalysis) confidence += 5; if (analysisResult.patternAnalysis) confidence += 5; return Math.min(confidence, 100); } /** * 生成优化建议 */ private generateSuggestions(analysisResult: any, params: SceneParams): string[] { const suggestions: string[] = []; // 基于灯光分析的建议 if (analysisResult.lightingAnalysis?.ambientAnalysis?.lightingMood?.primary === 'dramatic') { suggestions.push('考虑增加重点照明以突出戏剧效果'); } // 基于色彩分析的建议 if (analysisResult.enhancedColorAnalysis?.colorWheel?.saturation < 30) { suggestions.push('可以适当增加色彩饱和度以提升视觉效果'); } // 基于材质分析的建议 if (analysisResult.textureAnalysis?.surfaceProperties?.roughness?.level === 'high') { suggestions.push('建议平衡粗糙和光滑材质的比例'); } return suggestions; } /** * 生成风格哈希值 */ private generateStyleHash(params: SceneParams): string { const styleString = JSON.stringify({ lighting: params.lighting.primaryLight.type, mood: params.lighting.ambientLight.mood, style: params.style.renderStyle, atmosphere: params.environment.atmosphere }); // 简单的哈希函数 let hash = 0; for (let i = 0; i < styleString.length; i++) { const char = styleString.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; // 转换为32位整数 } return Math.abs(hash).toString(16).substring(0, 8); } /** * 获取默认场景参数 */ private getDefaultSceneParams(): SceneParams { return { lighting: { primaryLight: { type: 'natural', intensity: 70, temperature: 5500, direction: 'top' }, ambientLight: { strength: 40, mood: 'calm' }, shadows: { intensity: 50, softness: 60 } }, environment: { setting: 'indoor', atmosphere: 'modern', timeOfDay: 'afternoon', weatherCondition: 'sunny' }, composition: { viewAngle: 'medium', perspective: 'eye-level', focusPoint: 'center', depth: 70 }, style: { renderStyle: 'photorealistic', colorGrading: 'natural', textureDetail: 'high' } }; } /** * 初始化场景模板 */ private initializeSceneTemplates(): void { // 现代客厅 this.sceneTemplates.set(SceneTemplate.LIVING_ROOM_MODERN, { lighting: { primaryLight: { type: 'natural', intensity: 75, temperature: 5500, direction: 'front' }, ambientLight: { strength: 45, mood: 'calm' }, shadows: { intensity: 40, softness: 70 } }, environment: { setting: 'indoor', atmosphere: 'modern', timeOfDay: 'afternoon' }, composition: { viewAngle: 'wide', perspective: 'eye-level', focusPoint: 'center', depth: 80 }, style: { renderStyle: 'photorealistic', colorGrading: 'modern', textureDetail: 'high' } }); // 经典客厅 this.sceneTemplates.set(SceneTemplate.LIVING_ROOM_CLASSIC, { lighting: { primaryLight: { type: 'artificial', intensity: 65, temperature: 3000, direction: 'top' }, ambientLight: { strength: 55, mood: 'romantic' }, shadows: { intensity: 60, softness: 50 } }, environment: { setting: 'indoor', atmosphere: 'luxurious', timeOfDay: 'evening' }, composition: { viewAngle: 'medium', perspective: 'eye-level', focusPoint: 'center', depth: 75 }, style: { renderStyle: 'artistic', colorGrading: 'warm', textureDetail: 'high' } }); // 简约卧室 this.sceneTemplates.set(SceneTemplate.BEDROOM_MINIMAL, { lighting: { primaryLight: { type: 'natural', intensity: 60, temperature: 5000, direction: 'left' }, ambientLight: { strength: 30, mood: 'calm' }, shadows: { intensity: 35, softness: 80 } }, environment: { setting: 'indoor', atmosphere: 'minimal', timeOfDay: 'morning' }, composition: { viewAngle: 'medium', perspective: 'eye-level', focusPoint: 'center', depth: 60 }, style: { renderStyle: 'minimalist', colorGrading: 'natural', textureDetail: 'medium' } }); // 温馨卧室 this.sceneTemplates.set(SceneTemplate.BEDROOM_COZY, { lighting: { primaryLight: { type: 'artificial', intensity: 50, temperature: 2700, direction: 'multiple' }, ambientLight: { strength: 60, mood: 'romantic' }, shadows: { intensity: 45, softness: 75 } }, environment: { setting: 'indoor', atmosphere: 'cozy', timeOfDay: 'evening' }, composition: { viewAngle: 'close-up', perspective: 'eye-level', focusPoint: 'center', depth: 50 }, style: { renderStyle: 'soft', colorGrading: 'warm', textureDetail: 'high' } }); // 现代厨房 this.sceneTemplates.set(SceneTemplate.KITCHEN_CONTEMPORARY, { lighting: { primaryLight: { type: 'artificial', intensity: 85, temperature: 4000, direction: 'top' }, ambientLight: { strength: 40, mood: 'energetic' }, shadows: { intensity: 50, softness: 60 } }, environment: { setting: 'indoor', atmosphere: 'modern', timeOfDay: 'noon' }, composition: { viewAngle: 'wide', perspective: 'eye-level', focusPoint: 'center', depth: 70 }, style: { renderStyle: 'photorealistic', colorGrading: 'high-contrast', textureDetail: 'high' } }); // 添加更多模板... // 为了简洁,这里只展示几个主要模板的实现 // 实际项目中应该为所有SceneTemplate枚举值提供对应的配置 } }