ShowBase: significant improvements to ShowBase API documentation

Fixes #198
This commit is contained in:
rdb 2020-07-25 12:48:54 +02:00
parent 9d91274739
commit 43b5345588

View File

@ -85,6 +85,7 @@ def exitfunc():
# *seem* to cause anyone any problems.
class ShowBase(DirectObject.DirectObject):
#: The deprecated `.DConfig` interface for accessing config variables.
config = DConfig
notify = directNotify.newCategory("ShowBase")
@ -101,6 +102,8 @@ class ShowBase(DirectObject.DirectObject):
including this instance itself (under the name ``base``).
"""
#: Set if the want-dev Config.prc variable is enabled. By default, it
#: is set to True except when using Python with the -O flag.
self.__dev__ = self.config.GetBool('want-dev', __debug__)
builtins.__dev__ = self.__dev__
@ -113,13 +116,13 @@ class ShowBase(DirectObject.DirectObject):
if __debug__:
self.__autoGarbageLogging = self.__dev__ and self.config.GetBool('auto-garbage-logging', False)
## The directory containing the main Python file of this application.
#: The directory containing the main Python file of this application.
self.mainDir = ExecutionEnvironment.getEnvironmentVariable("MAIN_DIR")
self.main_dir = self.mainDir
## This contains the global appRunner instance, as imported from
## AppRunnerGlobal. This will be None if we are not running in the
## runtime environment (ie. from a .p3d file).
#: This contains the global appRunner instance, as imported from
#: `.AppRunnerGlobal`. This will be None if we are not running in the
#: runtime environment (ie. from a .p3d file). Deprecated.
self.appRunner = AppRunnerGlobal.appRunner
self.app_runner = self.appRunner
@ -154,13 +157,13 @@ class ShowBase(DirectObject.DirectObject):
self.wantTk = False
self.wantWx = False
## Fill this in with a function to invoke when the user "exits"
## the program by closing the main window.
#: Fill this in with a function to invoke when the user "exits"
#: the program by closing the main window.
self.exitFunc = None
## Add final-exit callbacks to this list. These will be called
## when sys.exit() is called, after Panda has unloaded, and
## just before Python is about to shut down.
#: Add final-exit callbacks to this list. These will be called
#: when sys.exit() is called, after Panda has unloaded, and
#: just before Python is about to shut down.
self.finalExitCallbacks = []
# Set up the TaskManager to reset the PStats clock back
@ -181,27 +184,34 @@ class ShowBase(DirectObject.DirectObject):
# we get a window-event.
self.__oldAspectRatio = None
## This is set to the value of the window-type config variable, but may
## optionally be overridden in the Showbase constructor. Should either be
## 'onscreen' (the default), 'offscreen' or 'none'.
#: This is set to the value of the window-type config variable, but may
#: optionally be overridden in the Showbase constructor. Should either
#: be 'onscreen' (the default), 'offscreen' or 'none'.
self.windowType = windowType
if self.windowType is None:
self.windowType = self.config.GetString('window-type', 'onscreen')
self.requireWindow = self.config.GetBool('require-window', 1)
## This is the main, or only window; see winList for a list of *all* windows.
#: This is the main, or only window; see `winList` for a list of *all* windows.
self.win = None
self.frameRateMeter = None
self.sceneGraphAnalyzerMeter = None
#: A list of all windows opened via `openWindow()`.
self.winList = []
self.winControls = []
self.mainWinMinimized = 0
self.mainWinForeground = 0
#: Contains the :class:`~panda3d.core.GraphicsPipe` object created by
#: `makeDefaultPipe()`.
self.pipe = None
#: The full list of :class:`~panda3d.core.GraphicsPipe` objects,
#: including any auxiliary pipes. Filled by `makeAllPipes()`.
self.pipeList = []
self.mouse2cam = None
self.buttonThrowers = None
self.mouseWatcher = None
#: The :class:`~panda3d.core.MouseWatcher` object, created by
#: `setupMouse()`.
self.mouseWatcherNode = None
self.pointerWatcherNodes = None
self.mouseInterface = None
@ -211,28 +221,37 @@ class ShowBase(DirectObject.DirectObject):
self.showVertices = None
self.deviceButtonThrowers = []
## This is a NodePath pointing to the Camera object set up for the 3D scene.
## This is usually a child of self.camera.
#: This is a :class:`~panda3d.core.NodePath` pointing to the
#: :class:`~panda3d.core.Camera` object set up for the 3D scene.
#: Usually a child of `camera`.
self.cam = None
#: Same as `cam`, but for the 2D scene graph.
self.cam2d = None
#: Same as `cam2d`, but for the 2D overlay scene graph.
self.cam2dp = None
## This is the NodePath that should be used to manipulate the camera. This
## is the node to which the default camera is attached.
#: This is the :class:`~panda3d.core.NodePath` that should be used to
#: manipulate the camera. It points at the node to which the default
#: camera (`cam`, `camNode`) is attached.
self.camera = None
#: Same as `camera`, but for the 2D scene graph. Parent of `cam2d`.
self.camera2d = None
#: Same as `camera2d`, but for the 2D overlay scene graph. Parent of
#: `cam2dp`.
self.camera2dp = None
## This is a list of all cameras created with makeCamera, including base.cam.
#: A list of all cameras created with `makeCamera()`, including `cam`.
self.camList = []
## Convenience accessor for base.cam.node()
#: Convenience accessor for base.cam.node(), containing a
#: :class:`~panda3d.core.Camera` object.
self.camNode = None
## Convenience accessor for base.camNode.get_lens()
#: Convenience accessor for base.camNode.get_lens(), containing a
#: :class:`~panda3d.core.Lens` object.
self.camLens = None
self.camFrustumVis = None
self.direct = None
## This is used to store the wx.Application object used when want-wx is
## set or base.startWx() is called.
#: This is used to store the wx.Application object used when want-wx is
#: set or `startWx()` is called.
self.wxApp = None
self.wxAppCreated = False
self.tkRoot = None
@ -251,7 +270,8 @@ class ShowBase(DirectObject.DirectObject):
from . import ShowBaseGlobal
self.hidden = ShowBaseGlobal.hidden
## The global graphics engine, ie. GraphicsEngine.getGlobalPtr()
#: The global :class:`~panda3d.core.GraphicsEngine`, as returned by
#: GraphicsEngine.getGlobalPtr()
self.graphicsEngine = GraphicsEngine.getGlobalPtr()
self.graphics_engine = self.graphicsEngine
self.setupRender()
@ -261,10 +281,11 @@ class ShowBase(DirectObject.DirectObject):
if self.wantRender2dp:
self.setupRender2dp()
## This is a placeholder for a CollisionTraverser. If someone
## stores a CollisionTraverser pointer here, we'll traverse it
## in the collisionLoop task.
#: A placeholder for a :class:`~panda3d.core.CollisionTraverser`. If
#: someone stores a CollisionTraverser pointer here, ShowBase will
#: traverse it automatically in the collisionLoop task, so you won't
#: need to call :meth:`~panda3d.core.CollisionTraverser.traverse()`
#: yourself every frame.
self.cTrav = 0
self.shadowTrav = 0
self.cTravStack = Stack()
@ -322,33 +343,35 @@ class ShowBase(DirectObject.DirectObject):
self.mouseInterface = self.trackball
self.useTrackball()
#: `.Loader.Loader` object.
self.loader = Loader.Loader(self)
self.graphicsEngine.setDefaultLoader(self.loader.loader)
## The global event manager, as imported from EventManagerGlobal.
#: The global event manager, as imported from `.EventManagerGlobal`.
self.eventMgr = eventMgr
## The global messenger, as imported from MessengerGlobal.
#: The global messenger, as imported from `.MessengerGlobal`.
self.messenger = messenger
## The global bulletin board, as imported from BulletinBoardGlobal.
#: The global bulletin board, as imported from `.BulletinBoardGlobal`.
self.bboard = bulletinBoard
## The global task manager, as imported from TaskManagerGlobal.
#: The global task manager, as imported from `.TaskManagerGlobal`.
self.taskMgr = taskMgr
self.task_mgr = taskMgr
## The global job manager, as imported from JobManagerGlobal.
#: The global job manager, as imported from `.JobManagerGlobal`.
self.jobMgr = jobMgr
## Particle manager
#: If `enableParticles()` has been called, this is the particle manager
#: as imported from :mod:`direct.particles.ParticleManagerGlobal`.
self.particleMgr = None
self.particleMgrEnabled = 0
## Physics manager
#: If `enableParticles()` has been called, this is the physics manager
#: as imported from :mod:`direct.showbase.PhysicsManagerGlobal`.
self.physicsMgr = None
self.physicsMgrEnabled = 0
self.physicsMgrAngular = 0
## This is the global input device manager, which keeps track of
## connected input devices.
#: This is the global :class:`~panda3d.core.InputDeviceManager`, which
#: keeps track of connected input devices.
self.devices = InputDeviceManager.getGlobalPtr()
self.__inputDeviceNodes = {}
@ -466,6 +489,8 @@ class ShowBase(DirectObject.DirectObject):
# Transition effects (fade, iris, etc)
from . import Transitions
#: `.Transitions.Transitions` object.
self.transitions = Transitions.Transitions(self.loader)
if self.win:
@ -486,12 +511,8 @@ class ShowBase(DirectObject.DirectObject):
else:
self.multiClientSleep = 0
# Offscreen buffer viewing utility.
# This needs to be allocated even if the viewer is off.
if self.wantRender2dp:
self.bufferViewer = BufferViewer(self.win, self.render2dp)
else:
self.bufferViewer = BufferViewer(self.win, self.render2d)
#: Utility for viewing offscreen buffers, see :mod:`.BufferViewer`.
self.bufferViewer = BufferViewer(self.win, self.render2dp if self.wantRender2dp else self.render2d)
if self.windowType != 'none':
if fStartDirect: # [gjeon] if this is False let them start direct manually
@ -635,6 +656,8 @@ class ShowBase(DirectObject.DirectObject):
Returns a GraphicsPipe from the indicated module,
e.g. 'pandagl' or 'pandadx9'. Does not affect base.pipe or
base.pipeList.
:rtype: panda3d.core.GraphicsPipe
"""
selection = GraphicsPipeSelection.getGlobalPtr()
@ -643,7 +666,7 @@ class ShowBase(DirectObject.DirectObject):
def makeAllPipes(self):
"""
Creates all GraphicsPipes that the system knows about and fill up
self.pipeList with them.
`pipeList` with them.
"""
selection = GraphicsPipeSelection.getGlobalPtr()
selection.loadAuxModules()
@ -685,27 +708,34 @@ class ShowBase(DirectObject.DirectObject):
Creates a window and adds it to the list of windows that are
to be updated every frame.
props is the WindowProperties that describes the window.
:param props: the :class:`~panda3d.core.WindowProperties` that
describes the window.
type is either 'onscreen', 'offscreen', or 'none'.
:param fbprops: the :class:`~panda3d.core.FrameBufferProperties`
indicating the requested framebuffer properties.
If keepCamera is true, the existing base.cam is set up to
render into the new window.
:param type: Either 'onscreen', 'offscreen', or 'none'.
If keepCamera is false but makeCamera is true, a new camera is
set up to render into the new window.
:param keepCamera: If True, the existing base.cam is set up to
render into the new window.
If unexposedDraw is not None, it specifies the initial value
of GraphicsWindow.setUnexposedDraw().
:param makeCamera: If True (and keepCamera is False), a new camera is
set up to render into the new window.
If callbackWindowDict is not None, a CallbackGraphicWindow is
created instead, which allows the caller to create the actual
window with its own OpenGL context, and direct Panda's
rendering into that window.
:param unexposedDraw: If not None, it specifies the initial value
of :meth:`~panda3d.core.GraphicsWindow.setUnexposedDraw()`.
If requireWindow is true, it means that the function should
raise an exception if the window fails to open correctly.
:param callbackWindowDict: If not None, a
:class:`~panda3d.core.CallbackGraphicWindow`
is created instead, which allows the caller
to create the actual window with its own
OpenGL context, and direct Panda's rendering
into that window.
:param requireWindow: If True, the function should raise an exception
if the window fails to open correctly.
:rtype: panda3d.core.GraphicsWindow
"""
# Save this lambda here for convenience; we'll use it to call
@ -968,16 +998,19 @@ class ShowBase(DirectObject.DirectObject):
self.graphicsEngine.renderFrame()
def openDefaultWindow(self, *args, **kw):
# Creates the main window for the first time, without being
# too particular about the kind of graphics API that is
# chosen. The suggested window type from the load-display
# config variable is tried first; if that fails, the first
# window type that can be successfully opened at all is
# accepted. Returns true on success, false otherwise.
#
# This is intended to be called only once, at application
# startup. It is normally called automatically unless
# window-type is configured to 'none'.
"""
Creates the main window for the first time, without being too
particular about the kind of graphics API that is chosen.
The suggested window type from the load-display config variable is
tried first; if that fails, the first window type that can be
successfully opened at all is accepted.
This is intended to be called only once, at application startup.
It is normally called automatically unless window-type is configured
to 'none'.
:returns: True on success, False on failure.
"""
startDirect = kw.get('startDirect', True)
if 'startDirect' in kw:
@ -998,9 +1031,8 @@ class ShowBase(DirectObject.DirectObject):
previous main window and open a new one, preserving the lens
properties in base.camLens.
The return value is true on success, or false on failure (in
which case base.win may be either None, or the previous,
closed window).
:returns: True on success, or False on failure (in which case base.win
may be either None, or the previous, closed window).
"""
keepCamera = kw.get('keepCamera', False)
@ -1130,7 +1162,6 @@ class ShowBase(DirectObject.DirectObject):
self.textureEnabled = 1
self.wireframeEnabled = 0
def setupRender2d(self):
"""
Creates the render2d scene graph, the primary scene graph for
@ -1344,9 +1375,10 @@ class ShowBase(DirectObject.DirectObject):
return aspectRatio
def getSize(self, win = None):
# Returns the actual size of the indicated (or main
# window), or the default size if there is not yet a
# main window.
"""
Returns the actual size of the indicated (or main window), or the
default size if there is not yet a main window.
"""
if win == None:
win = self.win
@ -1380,6 +1412,8 @@ class ShowBase(DirectObject.DirectObject):
If useCamera is not None, it is a NodePath to be used as the
camera to apply to the window, rather than creating a new
camera.
:rtype: panda3d.core.NodePath
"""
# self.camera is the parent node of all cameras: a node that
# we can move around to move all cameras as a group.
@ -1462,6 +1496,8 @@ class ShowBase(DirectObject.DirectObject):
"""
Makes a new camera2d associated with the indicated window, and
assigns it to render the indicated subrectangle of render2d.
:rtype: panda3d.core.NodePath
"""
dr = win.makeMonoDisplayRegion(*displayRegion)
dr.setSort(sort)
@ -1507,6 +1543,8 @@ class ShowBase(DirectObject.DirectObject):
"""
Makes a new camera2dp associated with the indicated window, and
assigns it to render the indicated subrectangle of render2dp.
:rtype: panda3d.core.NodePath
"""
dr = win.makeMonoDisplayRegion(*displayRegion)
dr.setSort(sort)
@ -1569,14 +1607,13 @@ class ShowBase(DirectObject.DirectObject):
using the indicated window. If the mouse has already been set
up for a different window, those structures are deleted first.
The return value is the ButtonThrower NodePath created for
this window.
:param fMultiWin: If True, then the previous mouse structures are not
deleted; instead, multiple windows are allowed to
monitor the mouse input. However, in this case, the
trackball controls are not set up, and must be set up
by hand if desired.
If fMultiWin is true, then the previous mouse structures are
not deleted; instead, multiple windows are allowed to monitor
the mouse input. However, in this case, the trackball
controls are not set up, and must be set up by hand if
desired.
:returns: The ButtonThrower NodePath created for this window.
"""
if not fMultiWin and self.buttonThrowers != None:
for bt in self.buttonThrowers:
@ -1707,18 +1744,30 @@ class ShowBase(DirectObject.DirectObject):
self.mouseWatcherNode.setGeometry(mouseViz.node())
def getAlt(self):
"""
Returns True if the alt key is currently held down.
"""
return self.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.alt())
def getShift(self):
"""
Returns True if the shift key is currently held down.
"""
return self.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.shift())
def getControl(self):
"""
Returns True if the control key is currently held down.
"""
return self.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.control())
def getMeta(self):
"""
Returns True if the meta key is currently held down.
"""
return self.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.meta())
@ -1784,6 +1833,11 @@ class ShowBase(DirectObject.DirectObject):
del self.__inputDeviceNodes[device]
def addAngularIntegrator(self):
"""
Adds a :class:`~panda3d.physics.AngularEulerIntegrator` to the default
physics manager. By default, only a
:class:`~panda3d.physics.LinearEulerIntegrator` is attached.
"""
if not self.physicsMgrAngular:
physics = importlib.import_module('panda3d.physics')
self.physicsMgrAngular = 1
@ -1791,6 +1845,15 @@ class ShowBase(DirectObject.DirectObject):
self.physicsMgr.attachAngularIntegrator(integrator)
def enableParticles(self):
"""
Enables the particle and physics managers, which are stored in
`particleMgr` and `physicsMgr` members, respectively. Also starts a
task to periodically update these managers.
By default, only a :class:`~panda3d.physics.LinearEulerIntegrator` is
attached to the physics manager. To attach an angular integrator,
follow this up with a call to `addAngularIntegrator()`.
"""
if not self.particleMgrEnabled:
# Use importlib to prevent this import from being picked up
# by modulefinder when packaging an application.
@ -1813,21 +1876,34 @@ class ShowBase(DirectObject.DirectObject):
self.taskMgr.add(self.updateManagers, 'manager-update')
def disableParticles(self):
"""
The opposite of `enableParticles()`.
"""
if self.particleMgrEnabled:
self.particleMgrEnabled = 0
self.physicsMgrEnabled = 0
self.taskMgr.remove('manager-update')
def toggleParticles(self):
"""
Calls `enableParticles()` or `disableParticles()` depending on the
current state.
"""
if self.particleMgrEnabled == 0:
self.enableParticles()
else:
self.disableParticles()
def isParticleMgrEnabled(self):
"""
Returns True if `enableParticles()` has been called.
"""
return self.particleMgrEnabled
def isPhysicsMgrEnabled(self):
"""
Returns True if `enableParticles()` has been called.
"""
return self.physicsMgrEnabled
def updateManagers(self, state):
@ -1839,6 +1915,11 @@ class ShowBase(DirectObject.DirectObject):
return Task.cont
def createStats(self, hostname=None, port=None):
"""
If want-pstats is set in Config.prc, or the `wantStats` member is
otherwise set to True, connects to the PStats server.
This is normally called automatically from the ShowBase constructor.
"""
# You can specify pstats-host in your Config.prc or use ~pstats/~aipstats
# The default is localhost
if not self.wantStats:
@ -1854,8 +1935,11 @@ class ShowBase(DirectObject.DirectObject):
PStatClient.connect(hostname, port)
return PStatClient.isConnected()
def addSfxManager(self, extraSfxManager):
"""
Adds an additional SFX audio manager to `sfxManagerList`, the list of
managers managed by ShowBase.
"""
# keep a list of sfx manager objects to apply settings to,
# since there may be others in addition to the one we create here
self.sfxManagerList.append(extraSfxManager)
@ -1865,6 +1949,10 @@ class ShowBase(DirectObject.DirectObject):
extraSfxManager.setActive(self.sfxActive)
def createBaseAudioManagers(self):
"""
Creates the default SFX and music manager. Called automatically from
the ShowBase constructor.
"""
self.sfxPlayer = SfxPlayer.SfxPlayer()
sfxManager = AudioManager.createAudioManager()
self.addSfxManager(sfxManager)
@ -1881,6 +1969,9 @@ class ShowBase(DirectObject.DirectObject):
# to a user request so sfxActive/musicActive represent how things
# *should* be, regardless of App/OS/HW state
def enableMusic(self, bEnableMusic):
"""
Enables or disables the music manager.
"""
# don't setActive(1) if no audiofocus
if self.AppHasAudioFocus and self.musicManagerIsValid:
self.musicManager.setActive(bEnableMusic)
@ -1900,6 +1991,9 @@ class ShowBase(DirectObject.DirectObject):
self.sfxManagerList[i].setActive(bEnabled)
def enableSoundEffects(self, bEnableSoundEffects):
"""
Enables or disables SFX managers.
"""
# don't setActive(1) if no audiofocus
if self.AppHasAudioFocus or (bEnableSoundEffects==0):
self.SetAllSfxEnables(bEnableSoundEffects)
@ -1916,6 +2010,10 @@ class ShowBase(DirectObject.DirectObject):
# come back ok when the app is switched back to
def disableAllAudio(self):
"""
Disables all SFX and music managers, meant to be called when the app
loses audio focus.
"""
self.AppHasAudioFocus = 0
self.SetAllSfxEnables(0)
if self.musicManagerIsValid:
@ -1923,6 +2021,11 @@ class ShowBase(DirectObject.DirectObject):
self.notify.debug("Disabling audio")
def enableAllAudio(self):
"""
Reenables the SFX and music managers that were active at the time
`disableAllAudio() was called. Meant to be called when the app regains
audio focus.
"""
self.AppHasAudioFocus = 1
self.SetAllSfxEnables(self.sfxActive)
if self.musicManagerIsValid:
@ -1933,6 +2036,9 @@ class ShowBase(DirectObject.DirectObject):
# backwards compatibility. Please do not add code here, add
# it to the loader.
def loadSfx(self, name):
"""
:deprecated: Use `.Loader.Loader.loadSfx()` instead.
"""
assert self.notify.warning("base.loadSfx is deprecated, use base.loader.loadSfx instead.")
return self.loader.loadSfx(name)
@ -1940,6 +2046,9 @@ class ShowBase(DirectObject.DirectObject):
# backwards compatibility. Please do not add code here, add
# it to the loader.
def loadMusic(self, name):
"""
:deprecated: Use `.Loader.Loader.loadMusic()` instead.
"""
assert self.notify.warning("base.loadMusic is deprecated, use base.loader.loadMusic instead.")
return self.loader.loadMusic(name)
@ -2070,7 +2179,6 @@ class ShowBase(DirectObject.DirectObject):
throw_new_frame()
return Task.cont
def __igLoopSync(self, state):
if __debug__:
# We render the watch variables for the onScreenDebug as soon
@ -2164,6 +2272,8 @@ class ShowBase(DirectObject.DirectObject):
Returns the current window background color. This assumes
the window is set up to clear the color each frame (this is
the normal setting).
:rtype: panda3d.core.VBase4
"""
if win == None:
win = self.win
@ -2195,47 +2305,74 @@ class ShowBase(DirectObject.DirectObject):
win.setClearColor(color)
def toggleBackface(self):
"""
Toggles between `backfaceCullingOn()` and `backfaceCullingOff()`.
"""
if self.backfaceCullingEnabled:
self.backfaceCullingOff()
else:
self.backfaceCullingOn()
def backfaceCullingOn(self):
"""
Disables two-sided rendering on the entire 3D scene graph.
"""
if not self.backfaceCullingEnabled:
self.render.setTwoSided(0)
self.backfaceCullingEnabled = 1
def backfaceCullingOff(self):
"""
Enables two-sided rendering on the entire 3D scene graph.
"""
if self.backfaceCullingEnabled:
self.render.setTwoSided(1)
self.backfaceCullingEnabled = 0
def toggleTexture(self):
"""
Toggles between `textureOn()` and `textureOff()`.
"""
if self.textureEnabled:
self.textureOff()
else:
self.textureOn()
def textureOn(self):
"""
Undoes the effects of a previous call to `textureOff()`.
"""
self.render.clearTexture()
self.textureEnabled = 1
def textureOff(self):
"""
Disables texturing on the entire 3D scene graph.
"""
self.render.setTextureOff(100)
self.textureEnabled = 0
def toggleWireframe(self):
"""
Toggles between `wireframeOn()` and `wireframeOff()`.
"""
if self.wireframeEnabled:
self.wireframeOff()
else:
self.wireframeOn()
def wireframeOn(self):
"""
Enables wireframe rendering on the entire 3D scene graph.
"""
self.render.setRenderModeWireframe(100)
self.render.setTwoSided(1)
self.wireframeEnabled = 1
def wireframeOff(self):
"""
Undoes the effects of a previous call to `wireframeOn()`.
"""
self.render.clearRenderMode()
render.setTwoSided(not self.backfaceCullingEnabled)
self.wireframeEnabled = 0
@ -2257,8 +2394,8 @@ class ShowBase(DirectObject.DirectObject):
def enableMouse(self):
"""
Reverse the effect of a previous call to disableMouse().
useDrive() also implicitly enables the mouse.
Reverse the effect of a previous call to `disableMouse()`.
`useDrive()` also implicitly enables the mouse.
"""
if self.mouse2cam:
self.mouse2cam.reparentTo(self.mouseInterface)
@ -2266,14 +2403,14 @@ class ShowBase(DirectObject.DirectObject):
def silenceInput(self):
"""
This is a heavy-handed way of temporarily turning off
all inputs. Bring them back with reviveInput().
all inputs. Bring them back with `reviveInput()`.
"""
if not self.__deadInputs:
self.__deadInputs = taskMgr.remove('dataLoop')
def reviveInput(self):
"""
Restores inputs after a previous call to silenceInput.
Restores inputs after a previous call to `silenceInput()`.
"""
if self.__deadInputs:
self.eventMgr.doEvents()
@ -2288,7 +2425,7 @@ class ShowBase(DirectObject.DirectObject):
def changeMouseInterface(self, changeTo):
"""
Switch mouse action
Change the mouse interface used to control the camera.
"""
# Get rid of the prior interface:
self.mouseInterface.detachNode()
@ -2303,7 +2440,7 @@ class ShowBase(DirectObject.DirectObject):
def useDrive(self):
"""
Switch mouse action to drive mode
Changes the mouse interface used for camera control to drive mode.
"""
if self.drive:
self.changeMouseInterface(self.drive)
@ -2313,14 +2450,16 @@ class ShowBase(DirectObject.DirectObject):
def useTrackball(self):
"""
Switch mouse action to trackball mode
Changes the mouse interface used for camera control to trackball mode.
"""
if self.trackball:
self.changeMouseInterface(self.trackball)
def toggleTexMem(self):
""" Toggles a handy texture memory watcher. See TexMemWatcher
for more information. """
"""
Toggles a handy texture memory watcher utility.
See :mod:`direct.showutil.TexMemWatcher` for more information.
"""
if self.texmem and not self.texmem.cleanedUp:
self.texmem.cleanup()
@ -2386,7 +2525,6 @@ class ShowBase(DirectObject.DirectObject):
self.showVertices = self.cam.attachNewNode(cam)
dr.setCamera(self.showVertices)
def oobe(self, cam = None):
"""
Enable a special "out-of-body experience" mouse-interface
@ -2397,12 +2535,12 @@ class ShowBase(DirectObject.DirectObject):
mouse events, if needed, may be sent to the normal node by
holding down the Control key.
This is different than useTrackball(), which simply changes
This is different than `useTrackball()`, which simply changes
the existing mouse action to a trackball interface. In fact,
OOBE mode doesn't care whether useDrive() or useTrackball() is
OOBE mode doesn't care whether `useDrive()` or `useTrackball()` is
in effect; it just temporarily layers a new trackball
interface on top of whatever the basic interface is. You can
even switch between useDrive() and useTrackball() while OOBE
even switch between `useDrive()` and `useTrackball()` while OOBE
mode is in effect.
This is a toggle; the second time this function is called, it
@ -2594,8 +2732,7 @@ class ShowBase(DirectObject.DirectObject):
generated by makeCubeMap(), namePrefix should contain the hash
mark ('#') character.
The return value is the filename if successful, or None if
there is a problem.
:returns: The filename if successful, or None if there is a problem.
"""
if source == None:
@ -2633,15 +2770,14 @@ class ShowBase(DirectObject.DirectObject):
the current scene, one in each of the six cube map directions.
This requires rendering a new frame.
Unlike screenshot(), source may only be a GraphicsWindow,
Unlike `screenshot()`, source may only be a GraphicsWindow,
GraphicsBuffer, or DisplayRegion; it may not be a Texture.
camera should be the node to which the cubemap cameras will be
parented. The default is the camera associated with source,
if source is a DisplayRegion, or base.camera otherwise.
The return value is the filename if successful, or None if
there is a problem.
:returns: The filename if successful, or None if there is a problem.
"""
if source == None:
@ -2703,8 +2839,7 @@ class ShowBase(DirectObject.DirectObject):
texture and because they are supported on a broader range of
hardware.
The return value is the filename if successful, or None if there
is a problem.
:returns: The filename if successful, or None if there is a problem.
"""
if source == None:
source = self.win
@ -2875,7 +3010,7 @@ class ShowBase(DirectObject.DirectObject):
def adjustWindowAspectRatio(self, aspectRatio):
""" This function is normally called internally by
windowEvent(), but it may also be called to explicitly adjust
`windowEvent()`, but it may also be called to explicitly adjust
the aspect ratio of the render/render2d DisplayRegion, by a
class that has redefined these. """
@ -2959,6 +3094,10 @@ class ShowBase(DirectObject.DirectObject):
self.finalizeExit()
def finalizeExit(self):
"""
Called by `userExit()` to quit the application. The default
implementation just calls `sys.exit()`.
"""
sys.exit()
# [gjeon] start wxPython
@ -3033,9 +3172,9 @@ class ShowBase(DirectObject.DirectObject):
self.taskMgr.step()
def wxRun(self):
""" This method replaces base.run() after we have called
spawnWxLoop(). Since at this point wxPython now owns the main
loop, this method is a call to wxApp.MainLoop(). """
""" This method replaces `run()` after we have called `spawnWxLoop()`.
Since at this point wxPython now owns the main loop, this method is a
call to wxApp.MainLoop(). """
if Thread.getCurrentThread().getCurrentTask():
# This happens in the p3d environment during startup.
@ -3117,9 +3256,9 @@ class ShowBase(DirectObject.DirectObject):
self.tkRoot.after(self.tkDelay, self.__tkTimerCallback)
def tkRun(self):
""" This method replaces base.run() after we have called
spawnTkLoop(). Since at this point Tkinter now owns the main
loop, this method is a call to tkRoot.mainloop(). """
""" This method replaces `run()` after we have called `spawnTkLoop()`.
Since at this point Tkinter now owns the main loop, this method is a
call to tkRoot.mainloop(). """
if Thread.getCurrentThread().getCurrentTask():
# This happens in the p3d environment during startup.
@ -3146,6 +3285,11 @@ class ShowBase(DirectObject.DirectObject):
return None
def getAxes(self):
"""
Loads and returns the ``models/misc/xyzAxis.bam`` model.
:rtype: panda3d.core.NodePath
"""
return loader.loadModel("models/misc/xyzAxis.bam")
def __doStartDirect(self):