1
0
forked from Rowland/EG
EG/demo/缩放位置修复说明.md
2025-07-10 09:19:51 +08:00

150 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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模型导入中的核心痛点。