#!/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("测试完成") 