EG/QPanda3D/Panda3DWorld.py
2025-07-25 11:04:59 +08:00

181 lines
6.2 KiB
Python

# -*- coding: utf-8-*-
"""
Module : Panda3DWorld
Author : Saifeddine ALOUI
Description :
Inherit this object to create your custom world
"""
import sys
import os
# 获取 RenderPipelineFile 的路径
render_pipeline_path = './RenderPipelineFile'
# 将该路径添加到 sys.path 中,确保 Python 能够找到它
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)
sys.path.insert(0, render_pipeline_path)
# 现在你可以导入 RenderPipelineFile 中的模块了
# 例如,如果你想导入 RenderPipelineFile 中的 RenderPipeline 模块
from RenderPipelineFile.rpcore import RenderPipeline
_global_render_pipeline = None
# PyQt imports
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
# Panda imports
from panda3d.core import *
# from panda3d.core import loadPrcFileData
# loadPrcFileData("", "window-type none") # Set Panda to draw its main window in an offscreen buffer
from direct.showbase.DirectObject import DirectObject
from panda3d.core import GraphicsOutput, Texture, ConfigVariableManager, WindowProperties
# Set up Panda environment
from direct.showbase.ShowBase import ShowBase
import platform
# Local imports
from QPanda3D.QMouseWatcherNode import QMouseWatcherNode
from rpcore.render_target import RenderTarget
__all__ = ["Panda3DWorld"]
_global_world_instance=None
import builtins
class Panda3DWorld(ShowBase):
"""
Panda3DWorld : A class to handle all panda3D world manipulation
"""
def __init__(self, width=1240, height=720, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1),
name="qpanda3D"):
global _global_world_instance
global _global_render_pipeline
_global_world_instance = self
sort = -100
self.parent = None
# self.width = width
# self.height = height
loadPrcFileData("", "win-size {} {}".format(width, height))
loadPrcFileData("", "show-frame-rate-meter 0")
loadPrcFileData("", f"win-size {width} {height}")
#loadPrcFileData("", "sync-video #t")
#loadPrcFileData("", "force-flush #t")
if (is_fullscreen):
loadPrcFileData("", "fullscreen #t")
else:
loadPrcFileData("", "window-type offscreen") # Set Panda to draw its main window in an offscreen buffer
#loadPrcFileData("", "show-frame-rate-meter 0") # 可选
self.render_pipeline = RenderPipeline()
self.render_pipeline.pre_showbase_init()
ShowBase.__init__(self)
self.render_pipeline.create(self)
_global_render_pipeline = self.render_pipeline
#from RenderPipelineFile.toolkit.material_editor.main import MaterialEditor
#self.screenTexture = self.render_pipeline._final_stage.target.color_tex
#self.screenTexture.setComponentType(Texture.T_unsigned_byte)
#self.screenTexture.setFormat(Texture.F_rgba8)
# 创建 Qt 能读的 RGBA8 贴图
self.qt_output_tex = Texture("qt_output_tex")
self.qt_output_tex.set_format(Texture.F_rgba8)
self.qt_output_tex.set_component_type(Texture.T_unsigned_byte)
#self.screenTexture.set_keep_ram_image(True)
# 添加到主窗口渲染输出,并指定复制回 CPU
self.win.add_render_texture(self.qt_output_tex, GraphicsOutput.RTM_copy_ram)
#self.screenTexture = Texture()
#self.screenTexture.setMinfilter(Texture.FTLinear)
#self.screenTexture.setFormat(Texture.FRgba32)
#self.screenTexture.set_wrap_u(Texture.WM_clamp)
#self.screenTexture.set_wrap_v(Texture.WM_clamp)
# buff_size_x = int(self.win.get_x_size() * size)
# buff_size_y = int(self.win.get_y_size() * size)
# winprops = WindowProperties()
# winprops.set_size(buff_size_x, buff_size_y)
#
#
# props = FrameBufferProperties()
# props.set_rgb_color(True)
# props.set_rgba_bits(8, 8, 8, 8)
# props.set_depth_bits(8)
# self.buff = self.graphicsEngine.make_output(
# self.pipe, name, sort,
# props, winprops,
# GraphicsPipe.BF_resizeable,
# self.win.get_gsg(), self.win)
#self.screenTexture = render_pipeline._final_stage.target.color_tex
#self.buff.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
# self.buff.set_sort(sort)
#self.cam = self.makeCamera(self.buff)
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
#self.render_pipeline._showbase.camera.reparentTo(self.render)
#base.camera.reparentTo(self.render)
#self.cam.reparentTo(self.render) # 可选同步
#render_pipeline.set_camera(self.cam)
#添加渲染效果后
self.cam = self.render_pipeline._showbase.cam
self.camNode = self.cam.node()
self.camLens = self.camNode.get_lens()
self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
#self.render_pipeline.daytime_mgr.update()
#
# if clear_color is None:
# self.buff.set_clear_active(GraphicsOutput.RTPColor, False)
# else:
# self.buff.set_clear_color(clear_color)
# self.buff.set_clear_active(GraphicsOutput.RTPColor, True)
self.disableMouse()
def render_pipeline(self):
"""获取 RenderPipeline 实例"""
return self._render_pipeline
def set_parent(self, parent: QWidget):
self.parent = parent
self.mouseWatcherNode = QMouseWatcherNode(parent)
def getAspectRatio(self, win = None):
if win is None and self.parent is not None:
return float(self.parent.width()) / float(self.parent.height())
else:
return super().getAspectRatio(win)
def get_render_pipeline():
"""获取全局 RenderPipeline 单例"""
if _global_render_pipeline is None:
raise RuntimeError(
"RenderPipeline has not been initialized yet. Please create a Panda3DWorld instance first.")
return _global_render_pipeline