Panda3d ShowBase多个实例



我目前正在尝试使用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年开始出现,甚至尝试了许多解决策略,其中一些由于版本变化而不再工作,有些根本不适用。例如这里问题:谁能给我一个方向是什么错了我的代码或如何规避这种行为?

从你的描述中,我假设你不是试图同时打开多个窗口,而是依次,一个接一个地关闭,而不退出Python解释器。

tl;博士

再次运行app = World()前先调用app.destroy()

Panda3d在创建ShowBase的第一个实例时设置全局变量,其中一个名为base的全局变量持有对ShowBase实例的引用。如果您尝试在之后创建另一个ShowBase实例,Panda3d将检查是否定义了base全局变量,如果已经存在,则抛出Attempt to spawn multiple ShowBase instances!异常。

您需要在创建新窗口之前清理之前的ShowBase实例。Panda3d设置了一个atexit清理函数来清理全局状态,但由于没有退出解释器,因此不会触发清理。您可以手动执行与清理函数相同的操作,即在ShowBase实例上调用.destroy()。这将删除全局引用,并允许您创建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()

相关内容

  • 没有找到相关文章

最新更新