panda3d showbase多个实例

发布于 2025-02-05 01:21:05 字数 1941 浏览 2 评论 0 原文

我目前正在尝试使用panda3d编写模拟器。在制作过程中,我遇到了一个相当烦人的问题。关闭Panda3D窗口并尝试运行新实例(我使用Spyder作为IDE)时,它会引发“异常:尝试产生多个Showbase实例”

除非我完全退出控制台,否则我将无法再次运行代码!

from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from panda3d.core import loadPrcFile
import simplepbr
from direct.task import Task
from panda3d.core import DirectionalLight
from panda3d.core import AntialiasAttrib


loadPrcFile('myconfig.prc')


class World(ShowBase):

    def __init__(self):

        ShowBase.__init__(self)
        simplepbr.init()
        # Load the environment model.
        self.scene = self.loader.loadModel(
            "model/Test.gltf")

        self.scene.reparentTo(self.render)
        self.scene.setScale(20, 20, 20)
        self.scene.setPos(0, 5, 0)

        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        alight = DirectionalLight('alight')
        alight.setColor((1, 1, 1, 1))
        #alight.setShadowCaster(True, 512, 512)
        alnp = self.render.attachNewNode(alight)
        alnp.setHpr(0, -10, 0)
        self.render.setAntialias(AntialiasAttrib.MAuto)
        self.render.setLight(alnp)
        # Define a procedure to move the camera.
        return

    def spinCameraTask(self, task):
        angleDegrees = task.time * 100.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(40 * sin(angleRadians), -
                           40.0 * cos(angleRadians), 10)
        self.camera.setHpr(angleDegrees, -5, 0)
        return Task.cont
app = World()
app.run()

因此,我很丧失了为什么会发生这种情况的解释。搜索网还给了我许多结果,即自2013年以来发生了这个问题,甚至尝试了许多解决方案策略,由于版本更改,有些问题不再起作用,而有些则不适用。例如在这里 问题: 谁能给我一个方向,我的代码有什么问题或如何规避这种行为?

I am currently trying to write a simulator using panda3d. While prototyping I came across a fairly annoying problem. When closing the panda3d window and trying to run a new instance (I am using Spyder as an IDE) it throws an "Exception: Attempt to spawn multiple ShowBase instances".

Unless I completely exit the console I cannot run my code again !

from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from panda3d.core import loadPrcFile
import simplepbr
from direct.task import Task
from panda3d.core import DirectionalLight
from panda3d.core import AntialiasAttrib


loadPrcFile('myconfig.prc')


class World(ShowBase):

    def __init__(self):

        ShowBase.__init__(self)
        simplepbr.init()
        # Load the environment model.
        self.scene = self.loader.loadModel(
            "model/Test.gltf")

        self.scene.reparentTo(self.render)
        self.scene.setScale(20, 20, 20)
        self.scene.setPos(0, 5, 0)

        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        alight = DirectionalLight('alight')
        alight.setColor((1, 1, 1, 1))
        #alight.setShadowCaster(True, 512, 512)
        alnp = self.render.attachNewNode(alight)
        alnp.setHpr(0, -10, 0)
        self.render.setAntialias(AntialiasAttrib.MAuto)
        self.render.setLight(alnp)
        # Define a procedure to move the camera.
        return

    def spinCameraTask(self, task):
        angleDegrees = task.time * 100.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(40 * sin(angleRadians), -
                           40.0 * cos(angleRadians), 10)
        self.camera.setHpr(angleDegrees, -5, 0)
        return Task.cont
app = World()
app.run()

So I am fairly at a loss of explanation why this happens. Searching the net also gave me many results that this problem occurs since 2013 and even tried many solution strategies from which some don't work anymore due to version changes and some just are not applicable. For instance Here
Question:
Can anyone give me a direction what is wrong with my code or how to circumvent this behavior ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

平安喜乐 2025-02-12 01:21:05

从您的描述中,我假设您不是要同时打开多个Windows ,而是依次 ,一个接一个地关闭,而无需退出Python Instrapter。

tl; dr

call app.destroy()再次运行 app = world()

说明

panda3d 当创建 showbase 的第一个实例时,其中一个名为 base 保存 showbase 实例的全局变量。如果您尝试创建另一个 showbase 实例之后,panda3d将检查 base base global是否被定义,并将抛出

在创建新窗口之前,您需要清理先前的 Showbase 实例。 panda3d设置清理功能清理全局状态,但是由于您没有退出解释器,因此您不会触发清理。 You can do the same thing as the cleanup function manually, which is to call

In [1]: from direct.showbase.ShowBase import ShowBase
In [2]: window = ShowBase()
In [3]: window.run() # Run the main loop, closing the window stops the main loop
In [4]: window.destroy()  # Manually clean up the old window
                          # `base.destroy()` would also work
In [5]: window = ShowBase()  # No errors after destroying the old window
In [6]: window.run()

From your description I'm assuming you're not trying to open multiple windows simultaneously but instead sequentially, one after another gets closed, without exiting the Python interpreter.

tl;dr

Call app.destroy() before running app = World() again.

Explanation

Panda3d sets up global variables when the first instance of ShowBase gets created, among them a global variable called base holding a reference to the ShowBase instance. If you try to create another ShowBase instance afterwards Panda3d will check if the base global is defined and will throw an Attempt to spawn multiple ShowBase instances! exception if one already exists.

You need to clean up the previous ShowBase instance before creating a new window. Panda3d sets up an atexit cleanup function that cleans up the global state, but since you're not exiting the interpreter you're not triggering the cleanup. You can do the same thing as the cleanup function manually, which is to call .destroy() on the ShowBase instance. This will remove the global references and allow you to create another instance of ShowBase.

In [1]: from direct.showbase.ShowBase import ShowBase
In [2]: window = ShowBase()
In [3]: window.run() # Run the main loop, closing the window stops the main loop
In [4]: window.destroy()  # Manually clean up the old window
                          # `base.destroy()` would also work
In [5]: window = ShowBase()  # No errors after destroying the old window
In [6]: window.run()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文