from direct.showbase.ShowBase import ShowBase  # 导入ShowBase类
from panda3d.core import WindowProperties  # 导入WindowProperties类
from panda3d.core import Vec3  # 导入Vec3类
from direct.task import Task  # 导入Task类
from direct.actor.Actor import Actor  # 导入Actor类
from panda3d.core import DirectionalLight  # 导入DirectionalLight类
from panda3d.core import Point3  # 导入Point3类
from panda3d.core import WindowProperties  # 导入WindowProperties类
from win32api import GetSystemMetrics
import pyautogui
import math

# 创建一个继承自ShowBase的类
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # 加载场景模型(场景树)
        self.scene = self.loader.loadModel('models/environment')  # 加载名为'models/environment'的模型
        # 将render设为场景模型的父节点
        self.scene.reparentTo(self.render)  # 将场景模型的父节点设置为render

        # 改变场景大小,并设置镜头初始位置
        self.scene.setScale(0.25, 0.25, 0.25)  # 缩小场景模型
        self.scene.setPos(-8, 42, 0)  # 设置场景模型的位置

        # 设置相机
        self.disableMouse()  # 禁用鼠标
        self.camera.setPos(0, -10, 0)  # 设置相机的位置
        self.camera.lookAt(0, 0, 0)  # 设置相机的朝向

        self.target = Point3(0, 0, 0)  # 初始化target为(0, 0, 0)
        self.distance = 10  # 初始化distance为10,摄像机与target点的距离为10个单位长度
        self.angleH = 0  # 初始化angleH为0
        self.angleP = 0  # 初始化angleP为0
        self.speedH = 0  # 初始化speedH为0
        self.speedP = 0  # 初始化speedP为0

        self.accept('mouse1', self.startDrag)  # 监听鼠标左键按下事件
        self.accept('mouse3', self.stopDrag)  # 监听鼠标右键按下事件

        self.isDragging = False  # 初始化isDragging为False
        self.lastPosition = None  # 初始化lastPosition为None

        self.taskMgr.add(self.rotateCameraTask, 'rotateCameraTask')  # 添加rotateCameraTask任务

        self.lastPosition = self.win.getPointer(0)  # 获取鼠标指针的位置
        pyautogui.mouseUp(button='middle')
        pyautogui.mouseUp(button='left')
        pyautogui.mouseUp(button='right')

    def startDrag(self):
        self.isDragging = True  # 将isDragging设置为True
        self.lastPosition = self.win.getPointer(0)  # 获取鼠标指针的位置
        wp = WindowProperties()  # 创建WindowProperties对象
        wp.setCursorHidden(True)  # 隐藏鼠标光标
        self.win.requestProperties(wp)  # 设置窗口属性
        pyautogui.mouseDown(button='middle')

    def stopDrag(self):
        if self.isDragging == True:
            try:
                pyautogui.mouseUp(button='middle')
            except:
                pass
            self.isDragging = False  # 将isDragging设置为False
            wp = WindowProperties()  # 创建WindowProperties对象
            wp.setCursorHidden(False)  # 显示鼠标光标
            self.win.requestProperties(wp)  # 设置窗口属性
            self.win.movePointer(0, self.win.getXSize() // 2, self.win.getYSize() // 2)  # 将鼠标指针移动到窗口中心
        else:
            self.startDrag()

    def rotateCameraTask(self, task):
        if self.isDragging:
            currentPosition = self.win.getPointer(0)  # 获取鼠标指针的位置
            deltaX = self.lastPosition.getX() - currentPosition.getX()  # 计算鼠标指针在x轴上的移动距离
            deltaY = self.lastPosition.getY() - currentPosition.getY()  # 计算鼠标指针在y轴上的移动距离

            self.speedH = deltaX * 0.1  # 根据鼠标指针在x轴上的移动距离设置水平旋转速度
            self.speedP = deltaY * 0.1  # 根据鼠标指针在y轴上的移动距离设置垂直旋转速度

            self.angleH += self.speedH  # 根据水平旋转速度更新水平旋转角度
            self.angleP += self.speedP  # 根据垂直旋转速度更新垂直旋转角度

            self.camera.setPos(self.target + Vec3(self.distance * math.sin(math.radians(self.angleH)) * math.cos(math.radians(self.angleP)),
                                                  self.distance * math.cos(math.radians(self.angleH)) * math.cos(math.radians(self.angleP)),
                                                  self.distance * math.sin(math.radians(self.angleP))))  # 设置相机的位置
            self.camera.lookAt(self.target)  # 设置相机的朝向
            self.lastPosition = currentPosition  # 更新lastPosition的值

        return task.cont  # 返回task.cont

# 创建MyApp类的实例并运行应用程序
app = MyApp()  # 创建MyApp类的实例
app.run()  # 运行应用程序

这个代码实现了一个基本的鼠标控制摄像机围绕一个点旋转的功能。您可以在代码中修改 self.distance 变量的值来调整摄像机与旋转中心的距离。

以下是一些额外的解释和建议:

  • 旋转中心: self.target 变量定义了旋转的中心点。您可以将其修改为不同的位置来改变旋转的中心点。
  • 旋转速度: self.speedHself.speedP 变量控制了旋转速度。您可以调整它们的值来改变旋转的速度。
  • 鼠标控制: 代码使用鼠标左键按下开始拖动,鼠标右键按下停止拖动。您可以根据需要修改这些按键。
  • 鼠标隐藏: 代码在拖动过程中隐藏鼠标光标,并使用 pyautogui 库来模拟鼠标点击。

您可以根据自己的需求进行进一步的修改和调整,例如添加更多功能,例如缩放、平移等等。

Panda3D 鼠标控制摄像机旋转:实现围绕指定点的视角移动

原文地址: https://www.cveoy.top/t/topic/nZBu 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录