116 lines
4.4 KiB
Python
116 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import sys
|
|
from direct.showbase.ShowBase import ShowBase
|
|
from panda3d.core import (
|
|
Point3, Point2, Vec3, CollisionTraverser, CollisionHandlerQueue,
|
|
CollisionNode, CollisionRay, CollisionSphere, BitMask32
|
|
)
|
|
|
|
class RayOffsetDebug(ShowBase):
|
|
def __init__(self):
|
|
ShowBase.__init__(self)
|
|
|
|
# 使用和主程序相同的相机设置
|
|
self.cam.setPos(-3.87655, -188.38084, 82.602684)
|
|
self.cam.lookAt(0, 0, 0)
|
|
|
|
print("=== 射线偏移调试 ===")
|
|
print(f"相机位置: {self.cam.getPos()}")
|
|
print(f"相机朝向: {self.cam.getHpr()}")
|
|
|
|
# 显示镜头参数
|
|
lens = self.cam.node().getLens()
|
|
print(f"镜头FOV: {lens.getFov()}")
|
|
print(f"宽高比: {lens.getAspectRatio()}")
|
|
|
|
# 设置射线检测
|
|
self.setupRayPicking()
|
|
|
|
# 测试不同位置的射线
|
|
self.testRayDirections()
|
|
|
|
print("调试完成")
|
|
|
|
def setupRayPicking(self):
|
|
"""设置射线检测"""
|
|
self.pickerNode = CollisionNode('mouseRay')
|
|
self.pickerRay = CollisionRay()
|
|
self.pickerNode.addSolid(self.pickerRay)
|
|
|
|
mask = BitMask32.bit(0)
|
|
self.pickerNode.setFromCollideMask(mask)
|
|
self.pickerNode.setIntoCollideMask(BitMask32.allOff())
|
|
|
|
self.pickerNP = self.render.attachNewNode(self.pickerNode)
|
|
|
|
def testRayDirections(self):
|
|
"""测试不同位置的射线方向"""
|
|
print("\n=== 射线方向测试 ===")
|
|
|
|
# 模拟不同的屏幕点击位置
|
|
test_cases = [
|
|
(0.0, 0.0, "屏幕中心"),
|
|
(-0.5, 0.0, "屏幕左侧"),
|
|
(0.5, 0.0, "屏幕右侧"),
|
|
(0.0, 0.5, "屏幕上方"),
|
|
(0.0, -0.5, "屏幕下方"),
|
|
(-0.006, 0.346, "用户点击位置"),
|
|
]
|
|
|
|
for norm_x, norm_y, description in test_cases:
|
|
print(f"\n--- {description}: ({norm_x:.3f}, {norm_y:.3f}) ---")
|
|
|
|
# 使用setFromLens方法
|
|
success = self.pickerRay.setFromLens(self.cam.node(), norm_x, norm_y)
|
|
if success:
|
|
rayOrigin = self.pickerRay.getOrigin()
|
|
rayDirection = self.pickerRay.getDirection()
|
|
|
|
print(f"射线起点: {rayOrigin}")
|
|
print(f"射线方向: {rayDirection}")
|
|
|
|
# 分析相机坐标系中的分量
|
|
camForward = self.cam.getMat().getRow3(1)
|
|
camRight = self.cam.getMat().getRow3(0)
|
|
camUp = self.cam.getMat().getRow3(2)
|
|
|
|
forwardComp = rayDirection.dot(camForward)
|
|
rightComp = rayDirection.dot(camRight)
|
|
upComp = rayDirection.dot(camUp)
|
|
|
|
print(f"相机坐标系分量:")
|
|
print(f" 前向: {forwardComp:.6f}")
|
|
print(f" 右向: {rightComp:.6f} (正=右, 负=左)")
|
|
print(f" 上向: {upComp:.6f} (正=上, 负=下)")
|
|
|
|
# 计算射线与(0,10,3)点的交点(地面上的一个点)
|
|
targetPoint = Point3(0, 10, 3)
|
|
rayToTarget = targetPoint - rayOrigin
|
|
|
|
# 检查射线是否指向这个方向
|
|
if rayDirection.dot(rayToTarget) > 0:
|
|
# 计算交点
|
|
distance = rayToTarget.length()
|
|
angle = rayDirection.dot(rayToTarget.normalized())
|
|
print(f"与参考点(0,10,3)的角度: {angle:.6f}")
|
|
|
|
# 预测射线在y=10平面上的交点
|
|
if abs(rayDirection.getY()) > 0.001:
|
|
t = (10 - rayOrigin.getY()) / rayDirection.getY()
|
|
if t > 0:
|
|
intersectionPoint = rayOrigin + rayDirection * t
|
|
print(f"在Y=10平面上的交点: {intersectionPoint}")
|
|
else:
|
|
print("射线不指向Y=10平面")
|
|
else:
|
|
print("射线平行于Y=10平面")
|
|
else:
|
|
print("射线背离参考点")
|
|
else:
|
|
print("setFromLens 失败")
|
|
|
|
if __name__ == "__main__":
|
|
app = RayOffsetDebug()
|
|
print("测试完成") |