# FBX模型缩放标准化位置修复说明 ## 问题描述 在FBX模型导入时,经常遇到子节点有大缩放值(如100)的问题。我们的缩放标准化功能可以将这些大缩放值调整为1,但最初的实现存在一个重要问题:**只调整了缩放,没有相应调整位置,导致子节点之间的距离变得过大**。 ## 问题分析 ### 原始FBX结构(示例) ``` 根节点 (缩放: 1.0, 位置: 0,0,0) ├── 子节点A (缩放: 100, 位置: 0,0,0) ├── 子节点B (缩放: 100, 位置: 60,5,320) └── 子节点C (缩放: 100, 位置: -16,-3,-347) ``` ### 问题:仅缩放标准化 ``` 根节点 (缩放: 1.0, 位置: 0,0,0) ├── 子节点A (缩放: 1.0, 位置: 0,0,0) ✓ 正常 ├── 子节点B (缩放: 1.0, 位置: 60,5,320) ✗ 距离过大! └── 子节点C (缩放: 1.0, 位置: -16,-3,-347) ✗ 距离过大! ``` **问题根源**:原来在100倍缩放下,(60,5,320)这样的位置是合理的,因为视觉上的有效距离会被缩放影响。但当缩放变成1时,这个位置就显得过大了。 ## 解决方案 ### 核心思路 当我们将子节点的缩放按比例缩小时,也要将它们的位置按相同比例缩小,以保持视觉上的相对关系。 ### 修复后的标准化 ``` 根节点 (缩放: 1.0, 位置: 0,0,0) ├── 子节点A (缩放: 1.0, 位置: 0,0,0) ✓ 正常 ├── 子节点B (缩放: 1.0, 位置: 0.6,0.05,3.2) ✓ 距离合理 └── 子节点C (缩放: 1.0, 位置: -0.16,-0.03,-3.47) ✓ 距离合理 ``` ## 技术实现 ### 修复前的代码 ```python def _applyScaleNormalization(self, node, normalize_factor, depth=0): # 只调整缩放 if max_scale_component > 10: new_scale = current_scale * normalize_factor node.setScale(new_scale) # 位置保持不变 - 这是问题所在! ``` ### 修复后的代码 ```python def _applyScaleNormalization(self, node, normalize_factor, depth=0): # 同时调整缩放和位置 if max_scale_component > 10: # 应用新的缩放 new_scale = current_scale * normalize_factor node.setScale(new_scale) # 同时调整位置:保持视觉相对位置一致 new_pos = current_pos * normalize_factor node.setPos(new_pos) ``` ## 效果对比 ### 修复前 - ✅ 缩放值正确(100 → 1.0) - ❌ 子节点距离过大(几百个单位) - ❌ 视觉布局异常 ### 修复后 - ✅ 缩放值正确(100 → 1.0) - ✅ 子节点距离合理(几个单位) - ✅ 视觉布局保持原有比例关系 ## 测试验证 使用测试脚本验证修复效果: ### 1. 位置测试脚本 ```bash cd demo python scale_position_test.py ``` 按T键运行完整的位置测试,检查: - 缩放因子是否正确(100 → 1.0) - 位置缩放是否正确(位置 × 0.01) - 相对位置关系是否保持 ### 2. FBX导入测试 ```bash cd demo python fbx_import_test.py ``` 导入实际的FBX文件,使用I键查看模型信息,确认: - 子节点缩放标准化为1.0 - 子节点位置为合理数值 - 整体视觉效果正常 ## 算法详解 ### 标准化因子计算 1. **收集缩放信息**:递归扫描所有节点的缩放值 2. **识别大缩放**:找出缩放值 > 10 的节点 3. **统计最常见值**:使用Counter找到最频繁的大缩放值(如100) 4. **计算标准化因子**:normalize_factor = 1.0 / common_large_scale ### 同步调整规则 ```python # 对于每个需要标准化的节点 if max_scale_component > 10: new_scale = current_scale * normalize_factor # 缩放调整 new_pos = current_pos * normalize_factor # 位置同步调整 ``` ## 配置选项 在`importModel`方法中提供灵活配置: ```python # 推荐配置(默认) world.importModel("model.fbx", apply_unit_conversion=False, # 不使用传统单位转换 normalize_scales=True) # 使用智能缩放标准化 # 传统配置 world.importModel("model.fbx", apply_unit_conversion=True, # 使用传统0.01根缩放 normalize_scales=False) # 不使用智能标准化 # 完全保持原始 world.importModel("model.fbx", apply_unit_conversion=False, # 不转换 normalize_scales=False) # 不标准化 ``` ## 总结 这个修复解决了FBX模型缩放标准化时的关键问题: 1. **保持视觉一致性**:子节点之间的相对位置关系不变 2. **简化层级结构**:避免复杂的缩放层级组合 3. **提高易用性**:导入后的模型结构直观易懂 4. **兼容性好**:不影响现有功能,提供可选配置 这确保了"一键导入,完美显示"的用户体验,解决了FBX模型导入中的核心痛点。