# 射线显示坐标系统修复说明 ## 🔍 问题描述 用户发现射线显示时是从场景中心点射出,而不是从相机位置射出。这违反了鼠标点击射线的基本原理。 ## ⚡ 问题原因 ### 1. **坐标系混淆** ```python # 原始错误代码 nearPoint = Point3() farPoint = Point3() self.world.cam.node().getLens().extrude(Point2(mx, my), nearPoint, farPoint) # 直接使用相机坐标系的点显示射线(错误!) self.showClickRay(nearPoint, farPoint, hitPos) ``` ### 2. **坐标系不匹配** - `lens.extrude()` 返回的是**相机坐标系**中的点 - 射线显示节点挂在 `render` 下,使用**世界坐标系** - 直接使用相机坐标系的点会导致射线从错误位置显示 ## 🛠 修复方案 ### 1. **正确的坐标变换** ```python # 获取相机坐标系中的射线点 nearPoint = Point3() farPoint = Point3() self.world.cam.node().getLens().extrude(Point2(mx, my), nearPoint, farPoint) # 转换到世界坐标系用于显示 worldNearPoint = self.world.render.getRelativePoint(self.world.cam, nearPoint) worldFarPoint = self.world.render.getRelativePoint(self.world.cam, farPoint) # 使用世界坐标系的点显示射线 self.showClickRay(worldNearPoint, worldFarPoint, hitPos) ``` ### 2. **碰撞检测保持不变** ```python # 碰撞检测仍使用相机坐标系(正确!) pickerNode = CollisionNode('mouseRay') pickerNP = self.world.cam.attachNewNode(pickerNode) # 相机子节点 direction = farPoint - nearPoint direction.normalize() pickerNode.addSolid(CollisionRay(nearPoint, direction)) # 相机坐标系 ``` ## 📐 坐标系统详解 ### **相机坐标系 vs 世界坐标系** | 坐标系 | 用途 | 特点 | |--------|------|------| | 相机坐标系 | 碰撞检测 | 以相机为原点,Z轴向前 | | 世界坐标系 | 射线显示 | 以场景为原点,固定坐标 | ### **为什么需要不同坐标系?** 1. **碰撞检测**: - 碰撞节点是相机的子节点 - 使用相机坐标系可以跟随相机移动 - 射线方向相对于相机计算 2. **射线显示**: - 射线节点是render的子节点 - 需要在世界坐标系中显示固定位置 - 从相机真实位置到点击点 ## 🎯 修复效果 ### **修复前** ``` 射线起点: (相机坐标系原点) = 场景中心附近 射线方向: 正确,但起点错误 显示效果: 射线从场景中心发射 ❌ ``` ### **修复后** ``` 射线起点: (相机世界位置) = 真实相机位置 射线方向: 正确,指向鼠标点击方向 显示效果: 射线从相机位置发射 ✅ ``` ## 🧪 验证方法 1. **启动射线测试**: ```bash python demo/ray_display_test.py ``` 2. **按R键开启射线显示** 3. **移动相机到不同位置** 4. **点击鼠标观察射线**: - 射线应该从当前相机位置开始 - 射线应该指向鼠标点击的方向 - 相机移动后射线起点应该跟随变化 ## 📋 技术要点 ### **关键API使用** ```python # 获取相机坐标系中的射线 lens.extrude(screen_point, near_point, far_point) # 坐标系转换 world_point = render.getRelativePoint(camera, camera_point) # 反向转换 camera_point = camera.getRelativePoint(render, world_point) ``` ### **调试输出** 现在会显示两套坐标: ``` 相机坐标系射线起点: (0, 1, 0) 世界坐标系射线起点: (-15.2, -42.3, 18.7) ``` 这样您就可以清楚地看到射线现在是从真实的相机位置发射,而不是从场景中心发射了!🎯