Spaces:
Runtime error
Runtime error
| // Debug Report Generator | |
| // Generates comprehensive debug reports for GLB generation | |
| export class DebugReportGenerator { | |
| generate(sceneData, sceneGraph, generationLog = [], warnings = [], errors = []) { | |
| const report = { | |
| timestamp: new Date().toISOString(), | |
| sceneName: sceneData.sceneName || "generated_scene", | |
| status: errors.length > 0 ? "ERROR" : warnings.length > 0 ? "WARNING" : "SUCCESS", | |
| summary: { | |
| totalNodes: sceneGraph.nodes?.length || 0, | |
| totalMeshes: sceneGraph.meshes?.length || 0, | |
| totalMaterials: sceneGraph.materials?.length || 0, | |
| totalLights: sceneGraph.lights?.length || 0, | |
| totalAnimations: sceneGraph.animations?.length || 0, | |
| hasAvatar: sceneData.avatar?.present || false, | |
| hasAudio: (sceneData.audio?.ambient?.length || 0) + (sceneData.audio?.spatial?.length || 0) > 0, | |
| hasEffects: Object.keys(sceneData.effects || {}).length > 0 | |
| }, | |
| sceneData: { | |
| environment: sceneData.environment || "room", | |
| lighting: { | |
| type: sceneData.lighting?.type || "day", | |
| lightsCount: sceneData.lighting?.lights?.length || 0, | |
| ambientStrength: sceneData.lighting?.ambient_strength || 0.3 | |
| }, | |
| objectsCount: sceneData.objects?.length || 0, | |
| avatar: sceneData.avatar?.present ? { | |
| name: sceneData.avatar.name || "Avatar", | |
| action: sceneData.avatar.action || "stand", | |
| position: sceneData.avatar.position || [0, 0, 0] | |
| } : null, | |
| audio: { | |
| ambient: sceneData.audio?.ambient?.length || 0, | |
| spatial: sceneData.audio?.spatial?.length || 0 | |
| }, | |
| effects: Object.keys(sceneData.effects || {}) | |
| }, | |
| sceneGraph: { | |
| nodes: sceneGraph.nodes?.map(n => ({ | |
| name: n.name, | |
| type: n.extras?.type || "unknown", | |
| hasMesh: n.mesh !== null && n.mesh !== undefined, | |
| hasLight: n.light !== null && n.light !== undefined, | |
| hasCamera: n.camera !== null && n.camera !== undefined, | |
| childrenCount: n.children?.length || 0 | |
| })) || [], | |
| meshes: sceneGraph.meshes?.map(m => ({ | |
| name: m.name, | |
| primitivesCount: m.primitives?.length || 0, | |
| hasMaterial: m.primitives?.[0]?.material !== undefined | |
| })) || [], | |
| materials: sceneGraph.materials?.map(m => ({ | |
| name: m.name, | |
| hasPBR: m.pbrMetallicRoughness !== undefined, | |
| hasEmission: m.emissiveFactor !== undefined | |
| })) || [], | |
| lights: sceneGraph.lights?.map(l => ({ | |
| name: l.name, | |
| type: l.type | |
| })) || [] | |
| }, | |
| generation: { | |
| log: generationLog, | |
| warnings: warnings, | |
| errors: errors, | |
| performance: { | |
| parseTime: null, | |
| graphTime: null, | |
| generationTime: null, | |
| totalTime: null | |
| } | |
| }, | |
| optimization: { | |
| compression: "none", | |
| textureFormat: "auto", | |
| meshOptimization: false, | |
| animationOptimization: false | |
| }, | |
| compatibility: { | |
| threejs: "compatible", | |
| babylon: "compatible", | |
| unity: "compatible", | |
| unreal: "compatible" | |
| }, | |
| recommendations: [] | |
| }; | |
| // Generate recommendations | |
| this.generateRecommendations(report, sceneData, sceneGraph); | |
| // Format as text | |
| return this.formatAsText(report); | |
| } | |
| generateRecommendations(report, sceneData, sceneGraph) { | |
| const recommendations = []; | |
| // Check for missing elements | |
| if (!sceneData.ground) { | |
| recommendations.push("WARNING: No ground plane defined. Scene may appear incomplete."); | |
| } | |
| if (sceneGraph.lights?.length === 0) { | |
| recommendations.push("WARNING: No lights defined. Scene will be dark."); | |
| } | |
| if (sceneGraph.meshes?.length === 0) { | |
| recommendations.push("WARNING: No meshes generated. Scene will be empty."); | |
| } | |
| // Check for optimization opportunities | |
| if (sceneGraph.meshes?.length > 50) { | |
| recommendations.push("OPTIMIZATION: Consider reducing mesh count or using instancing for better performance."); | |
| } | |
| if (sceneGraph.materials?.length > 20) { | |
| recommendations.push("OPTIMIZATION: Consider reusing materials to reduce draw calls."); | |
| } | |
| // Check for missing textures | |
| const materialsWithTextures = sceneGraph.materials?.filter(m => | |
| m.pbrMetallicRoughness?.baseColorTexture !== undefined | |
| ).length || 0; | |
| if (materialsWithTextures === 0 && sceneGraph.materials?.length > 0) { | |
| recommendations.push("INFO: No textures used. Consider adding textures for better visual quality."); | |
| } | |
| // Check animation | |
| if (sceneData.avatar?.present && !sceneData.avatar.action) { | |
| recommendations.push("INFO: Avatar present but no animation specified. Consider adding walk/stand animation."); | |
| } | |
| // Check audio | |
| if (sceneData.audio && (sceneData.audio.ambient?.length === 0 && sceneData.audio.spatial?.length === 0)) { | |
| recommendations.push("INFO: Audio nodes defined but empty. Consider adding ambient or spatial audio."); | |
| } | |
| report.recommendations = recommendations; | |
| } | |
| formatAsText(report) { | |
| let text = `GLB Generation Debug Report | |
| ${'='.repeat(60)} | |
| Generated: ${report.timestamp} | |
| Scene: ${report.sceneName} | |
| Status: ${report.status} | |
| ${'='.repeat(60)} | |
| SUMMARY | |
| ${'-'.repeat(60)} | |
| Total Nodes: ${report.summary.totalNodes} | |
| Total Meshes: ${report.summary.totalMeshes} | |
| Total Materials: ${report.summary.totalMaterials} | |
| Total Lights: ${report.summary.totalLights} | |
| Total Animations: ${report.summary.totalAnimations} | |
| Has Avatar: ${report.summary.hasAvatar ? 'Yes' : 'No'} | |
| Has Audio: ${report.summary.hasAudio ? 'Yes' : 'No'} | |
| Has Effects: ${report.summary.hasEffects ? 'Yes' : 'No'} | |
| ${'='.repeat(60)} | |
| SCENE DATA | |
| ${'-'.repeat(60)} | |
| Environment: ${report.sceneData.environment} | |
| Lighting Type: ${report.sceneData.lighting.type} | |
| Lighting Count: ${report.sceneData.lighting.lightsCount} | |
| Ambient Strength: ${report.sceneData.lighting.ambientStrength} | |
| Objects Count: ${report.sceneData.objectsCount} | |
| ${report.sceneData.avatar ? `Avatar: ${report.sceneData.avatar.name} (${report.sceneData.avatar.action})` : 'Avatar: None'} | |
| Audio: ${report.sceneData.audio.ambient} ambient, ${report.sceneData.audio.spatial} spatial | |
| Effects: ${report.sceneData.effects.join(', ') || 'None'} | |
| ${'='.repeat(60)} | |
| SCENE GRAPH | |
| ${'-'.repeat(60)} | |
| Nodes (${report.sceneGraph.nodes.length}): | |
| ${report.sceneGraph.nodes.map(n => | |
| ` - ${n.name} [${n.type}] (mesh: ${n.hasMesh}, light: ${n.hasLight}, camera: ${n.hasCamera}, children: ${n.childrenCount})` | |
| ).join('\n')} | |
| Meshes (${report.sceneGraph.meshes.length}): | |
| ${report.sceneGraph.meshes.map(m => | |
| ` - ${m.name} (${m.primitivesCount} primitives)` | |
| ).join('\n')} | |
| Materials (${report.sceneGraph.materials.length}): | |
| ${report.sceneGraph.materials.map(m => | |
| ` - ${m.name} (PBR: ${m.hasPBR}, Emission: ${m.hasEmission})` | |
| ).join('\n')} | |
| Lights (${report.sceneGraph.lights.length}): | |
| ${report.sceneGraph.lights.map(l => | |
| ` - ${l.name} [${l.type}]` | |
| ).join('\n')} | |
| ${'='.repeat(60)} | |
| GENERATION LOG | |
| ${'-'.repeat(60)} | |
| ${report.generation.log.length > 0 ? report.generation.log.join('\n') : 'No log entries'} | |
| ${report.generation.warnings.length > 0 ? ` | |
| WARNINGS: | |
| ${report.generation.warnings.map(w => ` - ${w}`).join('\n')} | |
| ` : ''} | |
| ${report.generation.errors.length > 0 ? ` | |
| ERRORS: | |
| ${report.generation.errors.map(e => ` - ${e}`).join('\n')} | |
| ` : ''} | |
| ${'='.repeat(60)} | |
| OPTIMIZATION | |
| ${'-'.repeat(60)} | |
| Compression: ${report.optimization.compression} | |
| Texture Format: ${report.optimization.textureFormat} | |
| Mesh Optimization: ${report.optimization.meshOptimization ? 'Enabled' : 'Disabled'} | |
| Animation Optimization: ${report.optimization.animationOptimization ? 'Enabled' : 'Disabled'} | |
| ${'='.repeat(60)} | |
| COMPATIBILITY | |
| ${'-'.repeat(60)} | |
| Three.js: ${report.compatibility.threejs} | |
| Babylon.js: ${report.compatibility.babylon} | |
| Unity: ${report.compatibility.unity} | |
| Unreal Engine: ${report.compatibility.unreal} | |
| ${report.recommendations.length > 0 ? ` | |
| ${'='.repeat(60)} | |
| RECOMMENDATIONS | |
| ${'-'.repeat(60)} | |
| ${report.recommendations.map(r => ` - ${r}`).join('\n')} | |
| ` : ''} | |
| ${'='.repeat(60)} | |
| END OF REPORT | |
| ${'='.repeat(60)} | |
| `; | |
| return text; | |
| } | |
| } | |