EG/demo/PICKING_SYSTEM_README.md
2025-07-02 09:49:59 +08:00

3.9 KiB
Raw Permalink Blame History

屏幕投影拾取系统使用说明

🎯 概述

为了解决您遇到的射线检测问题(射线偏向屏幕中心),我们实现了一个新的屏幕投影拾取系统它直接基于2D屏幕坐标进行对象选择比传统的3D射线检测更准确、更直观。

🚀 新系统优势

相比射线检测的优点

  1. 准确性高:完全对应用户的视觉感受,点击哪里就选中哪里
  2. 性能优秀不需要复杂的3D数学计算
  3. 稳定可靠:不会出现射线偏向屏幕中心的问题
  4. 支持任意形状:通过包围盒自动计算选择范围

传统射线检测的问题

  • 射线不是从相机发出,而是从近平面发出
  • 在Qt嵌入环境中容易出现坐标系转换问题
  • 微小的坐标偏移会导致射线方向计算错误

🔧 技术实现

核心原理

  1. 3D到2D投影:将对象的世界坐标投影到屏幕坐标
  2. 距离计算计算鼠标点击位置与对象屏幕位置的2D距离
  3. 智能选择:基于距离和优先级选择最合适的对象

关键特性

  • 自动半径计算:根据对象包围盒自动计算屏幕选择半径
  • 优先级系统:支持不同类型对象的选择优先级
  • 容差调节:可调节选择容差,使选择更容易或更精确
  • 自动更新:对象移动后自动更新位置信息

🎮 使用方法

在应用中的集成

# 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

🛠 技术细节

坐标系转换

# Qt坐标系 → 世界坐标系 → 屏幕坐标系
pixel_x = (screen_point.getX() + 1.0) * win_width * 0.5
pixel_y = (1.0 - screen_point.getY()) * win_height * 0.5

半径计算

  • 自动模式:基于对象包围盒的最大尺寸
  • 自定义模式:可为特定对象设置自定义选择半径
  • 距离补偿:远距离对象使用基于透视投影的估算

选择算法

# 计算选择分数
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编辑功能都正常工作

📝 总结

新的屏幕投影拾取系统解决了您遇到的射线偏向屏幕中心的问题,提供了更准确、更直观的对象选择体验。系统已完全集成到您的应用中,并保持了向后兼容性。