116 lines
3.9 KiB
Markdown
116 lines
3.9 KiB
Markdown
# 屏幕投影拾取系统使用说明
|
||
|
||
## 🎯 **概述**
|
||
|
||
为了解决您遇到的射线检测问题(射线偏向屏幕中心),我们实现了一个新的**屏幕投影拾取系统**,它直接基于2D屏幕坐标进行对象选择,比传统的3D射线检测更准确、更直观。
|
||
|
||
## 🚀 **新系统优势**
|
||
|
||
### ✅ **相比射线检测的优点**
|
||
1. **准确性高**:完全对应用户的视觉感受,点击哪里就选中哪里
|
||
2. **性能优秀**:不需要复杂的3D数学计算
|
||
3. **稳定可靠**:不会出现射线偏向屏幕中心的问题
|
||
4. **支持任意形状**:通过包围盒自动计算选择范围
|
||
|
||
### ❌ **传统射线检测的问题**
|
||
- 射线不是从相机发出,而是从近平面发出
|
||
- 在Qt嵌入环境中容易出现坐标系转换问题
|
||
- 微小的坐标偏移会导致射线方向计算错误
|
||
|
||
## 🔧 **技术实现**
|
||
|
||
### **核心原理**
|
||
1. **3D到2D投影**:将对象的世界坐标投影到屏幕坐标
|
||
2. **距离计算**:计算鼠标点击位置与对象屏幕位置的2D距离
|
||
3. **智能选择**:基于距离和优先级选择最合适的对象
|
||
|
||
### **关键特性**
|
||
- **自动半径计算**:根据对象包围盒自动计算屏幕选择半径
|
||
- **优先级系统**:支持不同类型对象的选择优先级
|
||
- **容差调节**:可调节选择容差,使选择更容易或更精确
|
||
- **自动更新**:对象移动后自动更新位置信息
|
||
|
||
## 🎮 **使用方法**
|
||
|
||
### **在应用中的集成**
|
||
```python
|
||
# 1. 系统已自动初始化
|
||
# 屏幕投影拾取器在 MyWorld.__init__() 中自动创建
|
||
|
||
# 2. 模型自动注册
|
||
# 导入的模型会自动注册到拾取器
|
||
|
||
# 3. 手动注册对象(可选)
|
||
self.screen_picker.registerObject(node_path, "对象名称", priority=1)
|
||
|
||
# 4. 更新对象位置(对象移动后)
|
||
self.screen_picker.updateObjectPositions()
|
||
```
|
||
|
||
### **键盘快捷键**
|
||
- **P键**:切换拾取方法(屏幕投影 ↔ 射线检测)
|
||
- **T键**:创建测试立方体(用于测试拾取功能)
|
||
- **R键**:切换射线调试显示
|
||
|
||
## 📋 **测试步骤**
|
||
|
||
1. **启动应用**:运行 `python3 test.py`
|
||
|
||
2. **创建测试对象**:按 **T键** 创建测试立方体
|
||
|
||
3. **测试选择**:
|
||
- 点击立方体附近区域
|
||
- 观察选择效果
|
||
|
||
4. **比较方法**:按 **P键** 切换拾取方法,比较效果差异
|
||
|
||
5. **导入模型**:拖拽3D模型文件到应用中测试
|
||
|
||
## 🔍 **调试信息**
|
||
|
||
系统会在控制台输出详细的调试信息:
|
||
|
||
```
|
||
=== 开始屏幕投影拾取 ===
|
||
鼠标位置: (372, 265)
|
||
选中对象: TestCube_1
|
||
```
|
||
|
||
## 🛠 **技术细节**
|
||
|
||
### **坐标系转换**
|
||
```python
|
||
# Qt坐标系 → 世界坐标系 → 屏幕坐标系
|
||
pixel_x = (screen_point.getX() + 1.0) * win_width * 0.5
|
||
pixel_y = (1.0 - screen_point.getY()) * win_height * 0.5
|
||
```
|
||
|
||
### **半径计算**
|
||
- **自动模式**:基于对象包围盒的最大尺寸
|
||
- **自定义模式**:可为特定对象设置自定义选择半径
|
||
- **距离补偿**:远距离对象使用基于透视投影的估算
|
||
|
||
### **选择算法**
|
||
```python
|
||
# 计算选择分数
|
||
distance_score = 1.0 - (distance / effective_radius)
|
||
priority_score = priority * 10.0
|
||
total_score = distance_score + priority_score
|
||
```
|
||
|
||
## 🎯 **使用建议**
|
||
|
||
1. **优先使用屏幕投影拾取**:对于大多数交互场景更准确
|
||
2. **射线检测作为备选**:某些特殊情况下仍然有用
|
||
3. **调整容差**:根据需要调整 `tolerance_multiplier` 参数
|
||
4. **设置优先级**:为不同类型的对象设置合适的选择优先级
|
||
|
||
## 🔄 **后向兼容**
|
||
|
||
- 原有的射线检测系统仍然保留
|
||
- 现在屏幕投影拾取为主要方法,射线检测为备选
|
||
- 所有现有的选择、拖拽、GUI编辑功能都正常工作
|
||
|
||
## 📝 **总结**
|
||
|
||
新的屏幕投影拾取系统解决了您遇到的射线偏向屏幕中心的问题,提供了更准确、更直观的对象选择体验。系统已完全集成到您的应用中,并保持了向后兼容性。 |