EG/core/world.py
2025-07-02 09:49:59 +08:00

204 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
from QPanda3D.Panda3DWorld import Panda3DWorld
from panda3d.core import (CardMaker, Vec4, Vec3, AmbientLight, DirectionalLight,
Point3, WindowProperties)
from direct.showbase.ShowBaseGlobal import globalClock
class CoreWorld(Panda3DWorld):
"""核心世界功能类 - 负责基础的3D世界设置和核心功能"""
def __init__(self):
super().__init__()
# 初始化基础属性
self.qtWidget = None # Qt部件引用用于获取准确的渲染区域尺寸
# 设置相机控制参数
self.cameraSpeed = 200.0 # 移动速度
self.cameraRotateSpeed = 40.0 # 旋转速度
# 鼠标控制相关变量
self.lastMouseX = 0
self.lastMouseY = 0
self.mouseRightPressed = False
# 初始化世界
self._setupCamera()
self._setupLighting()
self._setupGround()
self._loadFont()
print("✓ 核心世界初始化完成")
def _setupCamera(self):
"""设置相机位置和朝向"""
self.cam.setPos(0, -50, 20)
self.cam.lookAt(0, 0, 0)
print("✓ 相机设置完成")
def _setupLighting(self):
"""设置基础光照系统"""
# 环境光
alight = AmbientLight('alight')
alight.setColor((0.2, 0.2, 0.2, 1))
alnp = self.render.attachNewNode(alight)
self.render.setLight(alnp)
# 定向光(模拟太阳光)
dlight = DirectionalLight('dlight')
dlight.setColor((0.8, 0.8, 0.8, 1))
dlnp = self.render.attachNewNode(dlight)
dlnp.setHpr(45, -45, 0) # 设置光照方向
self.render.setLight(dlnp)
# 保存光源引用
self.ambient_light = alnp
self.directional_light = dlnp
print("✓ 光照系统设置完成")
def _setupGround(self):
"""创建地板"""
cm = CardMaker('ground')
cm.setFrame(-50, 50, -50, 50)
# 创建地板节点
self.ground = self.render.attachNewNode(cm.generate())
self.ground.setP(-90)
self.ground.setZ(-0.1)
self.ground.setColor(0.8, 0.8, 0.8, 1)
print("✓ 地板创建完成")
def _loadFont(self):
"""加载中文字体"""
try:
self.chinese_font = self.loader.loadFont('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc')
if not self.chinese_font:
print("警告: 无法加载中文字体,将使用默认字体")
else:
print("✓ 中文字体加载成功")
except:
print("警告: 无法加载中文字体,将使用默认字体")
self.chinese_font = None
def setQtWidget(self, widget):
"""设置Qt部件引用"""
self.qtWidget = widget
print(f"✓ 设置Qt部件引用: {widget}")
def getWindowSize(self):
"""获取准确的窗口尺寸"""
if self.qtWidget:
# 优先使用Qt部件的实际尺寸
width, height = self.qtWidget.getActualSize()
if width > 0 and height > 0:
return width, height
# 备用方案使用Panda3D窗口尺寸
if hasattr(self, 'win') and self.win:
width = self.win.getXSize()
height = self.win.getYSize()
print(f"从Panda3D窗口获取尺寸: {width} x {height}")
return width, height
# 最后的默认值
print("使用默认窗口尺寸: 800 x 600")
return 800, 600
# ==================== 相机控制功能 ====================
def wheelForward(self, data=None):
"""处理滚轮向前滚动(前进)"""
# 获取相机的前向向量
forward = self.cam.getMat().getRow3(1)
# 计算移动距离
distance = self.cameraSpeed * globalClock.getDt()
# 更新相机位置
currentPos = self.cam.getPos()
newPos = currentPos + forward * distance
self.cam.setPos(newPos)
def wheelBackward(self, data=None):
"""处理滚轮向后滚动(后退)"""
# 获取相机的前向向量
forward = self.cam.getMat().getRow3(1)
# 计算移动距离
distance = self.cameraSpeed * globalClock.getDt()
# 更新相机位置
currentPos = self.cam.getPos()
newPos = currentPos - forward * distance
self.cam.setPos(newPos)
def moveCamera(self, x, y, z):
"""移动相机位置(垂直移动)"""
# 获取相机的上向量
upVector = self.cam.getMat().getRow3(2)
# 计算移动距离
distance = self.cameraSpeed * globalClock.getDt()
# 更新相机位置
currentPos = self.cam.getPos()
newPos = currentPos + upVector * z * distance
self.cam.setPos(newPos)
# ==================== 鼠标事件处理 ====================
def mousePressEventRight(self, evt):
"""处理鼠标右键按下事件"""
print("右键按下")
self.mouseRightPressed = True
self.lastMouseX = evt['x']
self.lastMouseY = evt['y']
def mouseReleaseEventRight(self, evt):
"""处理鼠标右键释放事件"""
print("右键释放")
self.mouseRightPressed = False
def mouseMoveEvent(self, evt):
"""处理鼠标移动事件 - 只处理相机旋转"""
if not evt:
return
if self.mouseRightPressed:
# 计算鼠标移动距离
dx = evt.get('x', 0) - self.lastMouseX
dy = evt.get('y', 0) - self.lastMouseY
# 计算旋转角度
rotateSpeed = self.cameraRotateSpeed * globalClock.getDt()
# 更新相机朝向
currentH = self.cam.getH()
currentP = self.cam.getP()
# 限制俯仰角度在-90到90度之间
newP = max(-90, min(90, currentP - dy * rotateSpeed))
self.cam.setH(currentH - dx * rotateSpeed)
self.cam.setP(newP)
# 更新鼠标位置
self.lastMouseX = evt.get('x', 0)
self.lastMouseY = evt.get('y', 0)
# ==================== 其他基础功能 ====================
def getChineseFont(self):
"""获取中文字体"""
return self.chinese_font
def getGroundNode(self):
"""获取地板节点"""
return self.ground
def getAmbientLight(self):
"""获取环境光"""
return self.ambient_light
def getDirectionalLight(self):
"""获取定向光"""
return self.directional_light