#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
快速缩放测试脚本 - 验证FBX缩放标准化功能

测试用例：
1. 模拟带有大缩放值的FBX结构
2. 验证智能标准化功能
3. 对比修复前后的效果
"""

import sys
import os

# 添加主目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from panda3d.core import Vec3
from main import MyWorld


def test_scale_normalization():
    """测试缩放标准化功能"""
    print("🧪 FBX缩放标准化功能测试")
    print("="*50)
    
    # 创建测试世界
    world = MyWorld()
    
    # 创建模拟的FBX模型结构
    test_model = create_mock_fbx_model(world)
    
    print("\n📋 测试前的模型结构:")
    print_model_hierarchy(test_model)
    
    # 测试缩放标准化
    print("\n🔧 执行缩放标准化...")
    world.scene_manager._normalizeModelScales(test_model)
    
    print("\n📋 测试后的模型结构:")
    print_model_hierarchy(test_model)
    
    # 验证结果
    verify_normalization_results(test_model)
    
    print("\n✅ 测试完成!")


def create_mock_fbx_model(world):
    """创建模拟的FBX模型结构"""
    print("🏗️  创建模拟FBX模型结构...")
    
    # 创建根节点
    root = world.render.attachNewNode("MockFBXModel")
    root.setScale(1.0, 1.0, 1.0)  # 根节点正常缩放
    
    # 创建子节点（模拟FBX的大缩放值）
    child1 = root.attachNewNode("Mesh001")
    child1.setScale(100.0, 100.0, 100.0)  # 典型的FBX大缩放
    
    child2 = root.attachNewNode("Mesh002") 
    child2.setScale(100.0, 100.0, 100.0)  # 另一个大缩放
    
    child3 = root.attachNewNode("Bone001")
    child3.setScale(1.0, 1.0, 1.0)  # 正常缩放的骨骼
    
    # 创建孙子节点
    grandchild1 = child1.attachNewNode("SubMesh001")
    grandchild1.setScale(1.0, 1.0, 1.0)  # 正常缩放
    
    grandchild2 = child2.attachNewNode("SubMesh002")
    grandchild2.setScale(0.5, 0.5, 0.5)  # 小缩放
    
    # 创建一个异常的大缩放孙子节点
    grandchild3 = child3.attachNewNode("BigScale")
    grandchild3.setScale(50.0, 50.0, 50.0)  # 另一种大缩放
    
    print(f"   ✓ 创建了包含 {count_all_nodes(root)} 个节点的模型")
    return root


def count_all_nodes(node):
    """递归计算节点总数"""
    count = 1
    for i in range(node.getNumChildren()):
        count += count_all_nodes(node.getChild(i))
    return count


def print_model_hierarchy(model, depth=0):
    """打印模型层级结构"""
    indent = "  " * depth
    scale = model.getScale()
    max_scale = max(abs(scale.x), abs(scale.y), abs(scale.z))
    
    # 标记缩放状态
    if max_scale > 10:
        status = "🔴大缩放"
    elif max_scale < 1:
        status = "🟡小缩放"
    else:
        status = "🟢正常"
    
    print(f"{indent}📦 {model.getName()}: {scale} {status}")
    
    # 递归打印子节点
    for i in range(model.getNumChildren()):
        child = model.getChild(i)
        print_model_hierarchy(child, depth + 1)


def verify_normalization_results(model):
    """验证标准化结果"""
    print("\n🔍 验证标准化结果:")
    
    # 收集所有节点的缩放信息
    all_scales = []
    collect_all_scales(model, all_scales)
    
    # 统计分析
    large_scales = [s for s in all_scales if max(abs(s.x), abs(s.y), abs(s.z)) > 10]
    normal_scales = [s for s in all_scales if 0.1 <= max(abs(s.x), abs(s.y), abs(s.z)) <= 10]
    small_scales = [s for s in all_scales if max(abs(s.x), abs(s.y), abs(s.z)) < 0.1]
    
    print(f"   总节点数: {len(all_scales)}")
    print(f"   大缩放节点: {len(large_scales)} 个")
    print(f"   正常缩放节点: {len(normal_scales)} 个")
    print(f"   小缩放节点: {len(small_scales)} 个")
    
    # 验证结果
    if len(large_scales) == 0:
        print("   ✅ 成功：没有大缩放节点残留")
    else:
        print(f"   ❌ 失败：仍有 {len(large_scales)} 个大缩放节点")
        
    if len(normal_scales) >= len(all_scales) * 0.7:  # 至少70%是正常缩放
        print("   ✅ 成功：大部分节点缩放正常化")
    else:
        print("   ⚠️  警告：正常缩放节点比例较低")


def collect_all_scales(node, scales_list):
    """递归收集所有节点的缩放"""
    scales_list.append(node.getScale())
    
    for i in range(node.getNumChildren()):
        child = node.getChild(i)
        collect_all_scales(child, scales_list)


def test_scale_detection():
    """测试缩放检测算法"""
    print("\n🔬 测试缩放检测算法:")
    
    world = MyWorld()
    scene_manager = world.scene_manager
    
    # 创建测试数据
    test_scales = [
        {'scale': Vec3(100, 100, 100), 'name': 'Mesh001'},
        {'scale': Vec3(100, 100, 100), 'name': 'Mesh002'},
        {'scale': Vec3(100, 100, 100), 'name': 'Mesh003'},
        {'scale': Vec3(1, 1, 1), 'name': 'Bone001'},
        {'scale': Vec3(50, 50, 50), 'name': 'Special'},
        {'scale': Vec3(1, 1, 1), 'name': 'Normal001'},
    ]
    
    # 模拟检测过程
    large_scales = [info for info in test_scales if max(abs(info['scale'].x), abs(info['scale'].y), abs(info['scale'].z)) > 10]
    
    print(f"   发现 {len(large_scales)} 个大缩放节点:")
    for info in large_scales:
        max_scale = max(abs(info['scale'].x), abs(info['scale'].y), abs(info['scale'].z))
        print(f"     {info['name']}: {max_scale}")
    
    # 测试常见缩放值检测
    common_scale = scene_manager._findCommonLargeScale(large_scales)
    print(f"   检测到常见大缩放值: {common_scale}")
    
    if common_scale:
        normalize_factor = 1.0 / common_scale
        print(f"   计算的标准化因子: {normalize_factor}")
        print(f"   标准化后的示例: {100.0 * normalize_factor}")


if __name__ == "__main__":
    try:
        print("🚀 启动FBX缩放标准化测试")
        print("\n" + "="*60)
        
        # 运行主要测试
        test_scale_normalization()
        
        # 运行算法测试
        test_scale_detection()
        
        print("\n" + "="*60)
        print("🎉 所有测试完成!")
        
    except Exception as e:
        print(f"❌ 测试失败: {str(e)}")
        import traceback
        traceback.print_exc() 