rename out qp's

This commit is contained in:
David Rose 2002-04-10 18:24:38 +00:00
parent e4852a0ab5
commit 8738c24a1c
23 changed files with 164 additions and 1253 deletions

View File

@ -2,7 +2,6 @@
from PandaObject import *
import LODNode
import UsePgraph
class Actor(PandaObject, NodePath):
"""Actor class: Contains methods for creating, manipulating
@ -206,10 +205,7 @@ class Actor(PandaObject, NodePath):
# bounding volume for pieces that animate away from their
# original position. It's disturbing to see someone's hands
# disappear; better to cull the whole object or none of it.
if UsePgraph.use:
self.__geomNode.node().setFinal(1)
else:
self.__geomNode.arc().setFinal(1)
self.__geomNode.node().setFinal(1)
def delete(self):
try:
@ -711,10 +707,7 @@ class Actor(PandaObject, NodePath):
joint = bundle.findChild(jointName)
if (joint):
if UsePgraph.use:
joint.addNetTransform(node.node())
else:
joint.addNetTransform(node.arc())
joint.addNetTransform(node.node())
else:
Actor.notify.warning("no joint named %s!" % (jointName))
@ -839,18 +832,10 @@ class Actor(PandaObject, NodePath):
if mode == -2:
# Turn off depth test/write on the frontParts.
if UsePgraph.use:
numFrontParts = frontParts.getNumPaths()
for partNum in range(0, numFrontParts):
frontParts[partNum].setDepthWrite(0, 1)
frontParts[partNum].setDepthTest(0, 1)
else:
dw = DepthWriteTransition.off()
dt = DepthTestTransition(DepthTestProperty.MNone)
numFrontParts = frontParts.getNumPaths()
for partNum in range(0, numFrontParts):
frontParts[partNum].arc().setTransition(dw, 1)
frontParts[partNum].arc().setTransition(dt, 1)
numFrontParts = frontParts.getNumPaths()
for partNum in range(0, numFrontParts):
frontParts[partNum].setDepthWrite(0, 1)
frontParts[partNum].setDepthTest(0, 1)
# Find the back part.
backPart = root.find("**/" + backPartName)
@ -860,11 +845,7 @@ class Actor(PandaObject, NodePath):
if mode == -3:
# Draw as a decal.
if UsePgraph.use:
backPart.node().setEffect(DecalEffect.make())
else:
dt = DecalTransition()
backPart.arc().setTransition(dt)
backPart.node().setEffect(DecalEffect.make())
else:
# Reorder the backPart to be the first of its siblings.
backPart.reparentTo(backPart.getParent(), -1)

View File

@ -1,7 +1,6 @@
from PandaModules import *
from PandaObject import *
import math
import UsePgraph
X_AXIS = Vec3(1,0,0)
Y_AXIS = Vec3(0,1,0)
@ -47,12 +46,7 @@ class LineNodePath(NodePath):
def reset( self ):
self.lineSegs.reset()
if UsePgraph.use:
# New-style graph
self.lineNode.removeAllGeoms()
else:
# Old-style graph
self.lineNode.clear()
self.lineNode.removeAllGeoms()
def isEmpty( self ):
return self.lineSegs.isEmpty()
@ -216,6 +210,5 @@ def relHpr(nodePath, base, h, p, r):
# Set direct drawing style for an object
# Never light object or draw in wireframe
def useDirectRenderStyle(nodePath):
if UsePgraph.use:
nodePath.node().setAttrib(LightAttrib.makeAllOff())
nodePath.node().setAttrib(LightAttrib.makeAllOff())
nodePath.setRenderModeFilled()

View File

@ -1,7 +1,6 @@
from PandaObject import *
from DirectGeometry import *
from string import lower
import UsePgraph
class DirectLight(NodePath):
def __init__(self, light, parent):
@ -17,11 +16,7 @@ class DirectLight(NodePath):
node = light.upcastToPandaNode()
# Attach node to self
if UsePgraph.use:
self.assign(parent.attachNewNode(node))
else:
# Old scene graph no longer has lights.
pass
self.assign(parent.attachNewNode(node))
def getName(self):
return self.light.getName()
@ -109,17 +104,13 @@ class DirectLights(NodePath):
def allOn(self):
""" Turn on all DIRECT lights """
if UsePgraph.use:
# new-style scene graph
render.node().setAttrib(self.la)
render.node().setAttrib(self.la)
# Make sure there is a default material
render.setMaterial(Material())
def allOff(self):
""" Turn off all DIRECT lights """
if UsePgraph.use:
# new-style scene graph
render.node().clearAttrib(LightAttrib.getClassType())
render.node().clearAttrib(LightAttrib.getClassType())
def toggle(self):
""" Toggles light attribute, but doesn't toggle individual lights """

View File

@ -1,5 +1,4 @@
import FFIConstants
import UsePgraph
from string import *
@ -82,132 +81,6 @@ classRenameDictionary = {
'Frustumd' : 'FrustumD'
}
# The following is a bit of temporary kludginess to allow switching in
# the pgraph stuff for testing.
pgraphMethodRenameDictionary = {
'loadSync' : 'sploadSync',
'setCamera' : 'spsetCamera',
'qploadSync' : 'loadSync',
'setQpcamera' : 'setCamera',
}
pgraphClassRenameDictionary = {
'AnalogNode' : 'SpAnalogNode',
'AnimBundleNode' : 'SpAnimBundleNode',
'ButtonNode' : 'SpButtonNode',
'ButtonThrower' : 'SpButtonThrower',
'Camera' : 'SpCamera',
'CardMaker' : 'SpCardMaker',
'ChanConfig' : 'SpChanConfig',
'Character' : 'SpCharacter',
'CollisionEntry' : 'SpCollisionEntry',
'CollisionHandler' : 'SpCollisionHandler',
'CollisionHandlerEvent' : 'SpCollisionHandlerEvent',
'CollisionHandlerFloor' : 'SpCollisionHandlerFloor',
'CollisionHandlerPhysical' : 'SpCollisionHandlerPhysical',
'CollisionHandlerPusher' : 'SpCollisionHandlerPusher',
'CollisionHandlerQueue' : 'SpCollisionHandlerQueue',
'CollisionNode' : 'SpCollisionNode',
'CollisionTraverser' : 'SpCollisionTraverser',
'ColorLerpFunctor' : 'SpColorLerpFunctor',
'ColorScaleLerpFunctor' : 'SpColorScaleLerpFunctor',
'DataGraphTraverser' : 'SpDataGraphTraverser',
'DataNode' : 'SpDataNode',
'DialNode' : 'SpDialNode',
'DriveInterface' : 'SpDriveInterface',
'Fog' : 'SpFog',
'GeomNode' : 'SpGeomNode',
'HprLerpFunctor' : 'SpHprLerpFunctor',
'HprScaleLerpFunctor' : 'SpHprScaleLerpFunctor',
'LODNode' : 'SpLODNode',
'LensNode' : 'SpLensNode',
'LineSegs' : 'SpLineSegs',
'ModelNode' : 'SpModelNode',
'ModelPool' : 'SpModelPool',
'ModelRoot' : 'SpModelRoot',
'MouseAndKeyboard' : 'SpMouseAndKeyboard',
'MouseWatcher' : 'SpMouseWatcher',
'NodePath' : 'SpNodePath',
'NodePathCollection' : 'SpNodePathCollection',
'PGButton' : 'SpPGButton',
'PGEntry' : 'SpPGEntry',
'PGItem' : 'SpPGItem',
'PGTop' : 'SpPGTop',
'PGWaitBar' : 'SpPGWaitBar',
'PartBundleNode' : 'SpPartBundleNode',
'PosHprLerpFunctor' : 'SpPosHprLerpFunctor',
'PosHprScaleLerpFunctor' : 'SpPosHprScaleLerpFunctor',
'PosLerpFunctor' : 'SpPosLerpFunctor',
'ScaleLerpFunctor' : 'SpScaleLerpFunctor',
'SceneGraphReducer' : 'SpSceneGraphReducer',
'SequenceNode' : 'SpSequenceNode',
'TextNode' : 'SpTextNode',
'Trackball' : 'SpTrackball',
'TrackerNode' : 'SpTrackerNode',
'Transform2SG' : 'SpTransform2SG',
'VirtualMouse' : 'SpVirtualMouse',
'QpAnalogNode' : 'AnalogNode',
'QpAnimBundleNode' : 'AnimBundleNode',
'QpButtonNode' : 'ButtonNode',
'QpButtonThrower' : 'ButtonThrower',
'QpCamera' : 'Camera',
'QpCardMaker' : 'CardMaker',
'QpChanConfig' : 'ChanConfig',
'QpCharacter' : 'Character',
'QpCollisionEntry' : 'CollisionEntry',
'QpCollisionHandler' : 'CollisionHandler',
'QpCollisionHandlerEvent' : 'CollisionHandlerEvent',
'QpCollisionHandlerFloor' : 'CollisionHandlerFloor',
'QpCollisionHandlerPhysical': 'CollisionHandlerPhysical',
'QpCollisionHandlerPusher' : 'CollisionHandlerPusher',
'QpCollisionHandlerQueue' : 'CollisionHandlerQueue',
'QpCollisionNode' : 'CollisionNode',
'QpCollisionTraverser' : 'CollisionTraverser',
'QpColorLerpFunctor' : 'ColorLerpFunctor',
'QpColorScaleLerpFunctor' : 'ColorScaleLerpFunctor',
'QpDataGraphTraverser' : 'DataGraphTraverser',
'QpDataNode' : 'DataNode',
'QpDialNode' : 'DialNode',
'QpDriveInterface' : 'DriveInterface',
'QpFog' : 'Fog',
'QpGeomNode' : 'GeomNode',
'QpHprLerpFunctor' : 'HprLerpFunctor',
'QpHprScaleLerpFunctor' : 'HprScaleLerpFunctor',
'QpLODNode' : 'LODNode',
'QpLensNode' : 'LensNode',
'QpLineSegs' : 'LineSegs',
'QpModelNode' : 'ModelNode',
'QpModelPool' : 'ModelPool',
'QpModelRoot' : 'ModelRoot',
'QpMouseAndKeyboard' : 'MouseAndKeyboard',
'QpMouseWatcher' : 'MouseWatcher',
'QpNodePath' : 'NodePath',
'QpNodePathCollection' : 'NodePathCollection',
'QpPGButton' : 'PGButton',
'QpPGEntry' : 'PGEntry',
'QpPGItem' : 'PGItem',
'QpPGTop' : 'PGTop',
'QpPGWaitBar' : 'PGWaitBar',
'QpPartBundleNode' : 'PartBundleNode',
'QpPosHprLerpFunctor' : 'PosHprLerpFunctor',
'QpPosHprScaleLerpFunctor' : 'PosHprScaleLerpFunctor',
'QpPosLerpFunctor' : 'PosLerpFunctor',
'QpScaleLerpFunctor' : 'ScaleLerpFunctor',
'QpSceneGraphReducer' : 'SceneGraphReducer',
'QpSequenceNode' : 'SequenceNode',
'QpTextNode' : 'TextNode',
'QpTrackball' : 'Trackball',
'QpTrackerNode' : 'TrackerNode',
'QpTransform2SG' : 'Transform2SG',
'QpVirtualMouse' : 'VirtualMouse',
}
if UsePgraph.use:
methodRenameDictionary.update(pgraphMethodRenameDictionary)
classRenameDictionary.update(pgraphClassRenameDictionary)
def checkKeyword(cppName):
if cppName in pythonKeywords:

View File

@ -1,5 +1,4 @@
from DirectFrame import *
import UsePgraph
"""
import DirectWaitBar
@ -82,10 +81,7 @@ class DirectWaitBar(DirectFrame):
# Render a frame out-of-sync with the igloop to update the
# window right now. This allows the wait bar to be updated
# even though we are not normally rendering frames.
if UsePgraph.use:
base.graphicsEngine.renderFrame()
else:
base.win.renderAndUpdate()
base.graphicsEngine.renderFrame()
def finish(self):
# Fill the bar in N frames

View File

@ -2,7 +2,6 @@
from PandaModules import *
from DirectNotifyGlobal import *
import UsePgraph
# You can specify a phaseChecker callback to check
# a modelPath to see if it is being loaded in the correct
@ -34,10 +33,7 @@ class Loader:
phaseChecker(modelPath)
node = self.loader.loadSync(Filename(modelPath))
if (node != None):
if UsePgraph.use:
nodePath = NodePath(node)
else:
nodePath = self.base.hidden.attachNewNode(node)
nodePath = NodePath(node)
if fMakeNodeNamesUnique:
self.makeNodeNamesUnique(nodePath, 0)
else:
@ -54,10 +50,7 @@ class Loader:
phaseChecker(modelPath)
node = ModelPool.loadModel(modelPath)
if (node != None):
if UsePgraph.use:
nodePath = NodePath(node)
else:
nodePath = self.base.hidden.attachNewNode(node)
nodePath = NodePath(node)
else:
nodePath = None
return nodePath
@ -99,10 +92,7 @@ class Loader:
phaseChecker(modelPath)
node = ModelPool.loadModel(modelPath)
if (node != None):
if UsePgraph.use:
return (NodePath(node.copySubgraph()))
else:
return (NodePath(node).copyTo(self.base.hidden))
return (NodePath(node.copySubgraph()))
else:
return None

View File

@ -66,7 +66,10 @@ class ShowBase:
fsmRedefine = self.config.GetBool('fsm-redefine', 0)
State.FsmRedefine = fsmRedefine
self.hidden = NodePath(NamedNode('hidden'))
self.hidden = NodePath('hidden')
# We need a graphics engine to manage the actual rendering.
self.graphicsEngine = GraphicsEngine()
self.setupRender()
self.setupRender2d()
@ -79,6 +82,10 @@ class ShowBase:
# Ditto for an AppTraverser.
self.appTrav = 0
# This is the DataGraph traverser, which we might as well
# create now.
self.dgTrav = DataGraphTraverser()
# base.win is the main, or only window; base.winList is a list of
# *all* windows. Similarly with base.pipeList and base.camList.
self.win = None
@ -89,12 +96,7 @@ class ShowBase:
self.camList = []
self.camNode = None
self.camLens = None
# base.camera is a little different; rather than referring to
# base.cameraList[0], it is instead the parent node of all
# cameras in base.cameraList. That way, multiple cameras can
# easily be dragged around by moving the one node.
self.camera = self.render.attachNewNode('camera')
self.camera = None
self.cameraList = []
self.groupList = []
self.camera2d = self.render2d.attachNewNode('camera2d')
@ -190,13 +192,14 @@ class ShowBase:
self.pipe = makeGraphicsPipe()
self.pipeList.append(self.pipe)
chanConfig = makeGraphicsWindow(self.pipe, self.render.arc())
chanConfig = makeGraphicsWindow(self.pipe, self.render)
win = chanConfig.getWin()
if self.win == None:
self.win = win
self.winList.append(win)
self.graphicsEngine.addWindow(win)
self.getCameras(chanConfig)
@ -207,11 +210,12 @@ class ShowBase:
Creates the render scene graph, the primary scene graph for
rendering 3-d geometry.
"""
self.renderTop = NodePath(NamedNode('renderTop'))
self.render = self.renderTop.attachNewNode('render')
self.render = NodePath('render')
self.render.setTwoSided(0)
self.backfaceCullingEnabled = 1
self.textureEnabled = 1
self.wireframeEnabled = 0
# Set a default "off color" (i.e. use poly color) for color transitions
self.render.setColorOff()
def setupRender2d(self):
"""setupRender2d(self)
@ -221,8 +225,7 @@ class ShowBase:
3-d geometry in the window.
"""
self.render2dTop = NodePath(NamedNode('render2dTop'))
self.render2d = self.render2dTop.attachNewNode('render2d')
self.render2d = NodePath('render2d')
# Set up some overrides to turn off certain properties which
# we probably won't need for 2-d objects.
@ -232,12 +235,12 @@ class ShowBase:
# by the previously-drawn 3-d scene--we don't want to pay for
# a clear operation, but we also don't want to collide with
# that depth buffer.
dt = DepthTestTransition(DepthTestProperty.MNone)
dw = DepthWriteTransition.off()
lt = LightTransition.allOff()
self.render2d.arc().setTransition(dt, 1)
self.render2d.arc().setTransition(dw, 1)
self.render2d.arc().setTransition(lt, 1)
dt = DepthTestAttrib.make(DepthTestAttrib.MNone)
dw = DepthWriteAttrib.make(DepthWriteAttrib.MOff)
#lt = LightTransition.allOff()
self.render2d.node().setAttrib(dt, 1)
self.render2d.node().setAttrib(dw, 1)
#self.render2d.node().setAttrib(lt, 1)
self.render2d.setMaterialOff(1)
self.render2d.setTwoSided(1, 1)
@ -251,6 +254,7 @@ class ShowBase:
# For now, we assume that the window will have an aspect ratio
# matching that of a traditional PC screen (w / h) = (4 / 3)
self.aspectRatio = self.config.GetFloat('aspect-ratio', (4.0 / 3.0))
self.aspect2d = self.render2d.attachNewNode(PGTop("aspect2d"))
self.aspect2d.setScale(1.0 / self.aspectRatio, 1.0, 1.0)
@ -281,10 +285,10 @@ class ShowBase:
lens.setFilmOffset((right + left) / 2.0, (top + bottom) / 2.0)
lens.setNearFar(-1000, 1000)
cam2dNode.setLens(lens)
cam2dNode.setScene(self.render2d.getTopNode())
dr.setCamera(cam2dNode)
cam2dNode.setScene(self.render2d)
camera2d = self.camera2d.attachNewNode(cam2dNode)
dr.setCamera(camera2d)
return camera2d
@ -295,10 +299,10 @@ class ShowBase:
devices.
"""
self.dataRoot = NodePath(NamedNode('dataRoot'), DataRelation.getClassType())
self.dataRoot = NodePath('dataRoot')
# Cache the node so we do not ask for it every frame
self.dataRootNode = self.dataRoot.node()
self.dataUnused = NodePath(NamedNode('dataUnused'), DataRelation.getClassType())
self.dataUnused = NodePath('dataUnused')
def setupMouse(self, win):
@ -309,8 +313,6 @@ class ShowBase:
per application.
"""
print 'setup mouse'
# We create both a MouseAndKeyboard object and a MouseWatcher object
# for the window. The MouseAndKeyboard generates mouse events and
# mouse button/keyboard events; the MouseWatcher passes them through
@ -329,32 +331,24 @@ class ShowBase:
mb.addButton(KeyboardButton.alt())
self.mouseWatcherNode.setModifierButtons(mb)
# We also create a DataValve object above the trackball/drive
# interface, which will allow us to switch some of the mouse
# control, without switching all of it, to another object
# later (for instance, to enable OOBE mode--see oobe(),
# below.)
self.mouseValve = self.mouseWatcher.attachNewNode(DataValve('mouseValve'))
# This Control object can be used to turn on and off mouse &
# keyboard messages to the DriveInterface.
self.mouseControl = DataValve.Control()
self.mouseValve.node().setControl(0, self.mouseControl)
# This Control object is always kept on, handy to have.
self.onControl = DataValve.Control()
# Now we have the main trackball & drive interfaces.
# useTrackball() and useDrive() switch these in and out; only
# one is in use at a given time.
self.trackball = self.dataUnused.attachNewNode(Trackball('trackball'))
self.drive = self.dataUnused.attachNewNode(DriveInterface('drive'))
self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
self.mouse2cam.node().setArc(self.camera.arc())
self.useDrive()
self.mouse2cam.node().setNode(self.camera.node())
# The default is trackball mode, which is more convenient for
# ad-hoc development in Python using ShowBase. Applications
# can explicitly call base.useDrive() if they prefer a drive
# interface.
self.mouseInterface = self.trackball
self.useTrackball()
# A ButtonThrower to generate events from the mouse and
# keyboard buttons as they are pressed.
self.buttonThrower = self.mouseWatcher.attachNewNode(ButtonThrower())
self.buttonThrower = self.mouseWatcher.attachNewNode(ButtonThrower('buttons'))
# Specialize the events based on whether the modifier keys are
# being held down.
@ -380,12 +374,12 @@ class ShowBase:
lilsmiley.reparentTo(mouseViz)
# Scale the smiley face to 32x32 pixels.
lilsmiley.setScale(32.0 / self.win.getHeight() / self.aspectRatio, 1.0, 32.0 / self.win.getHeight())
self.mouseWatcherNode.setGeometry(mouseViz.arc())
#self.mouseWatcherNode.setGeometry(mouseViz)
def getCameras(self, chanConfig):
"""getCameras(self, chanConfig)
"""
getCameras(self, chanConfig)
Extracts the camera(s) out of the ChanConfig record, parents
them all to base.camera, and adds them to base.cameraList.
"""
@ -394,7 +388,7 @@ class ShowBase:
# be more than one display region/camera node beneath each
# one.
for i in range(chanConfig.getNumGroups()):
camera = self.camera.attachNewNode(chanConfig.getGroupNode(i))
camera = self.render.attachNewNode(chanConfig.getGroupNode(i))
cam = camera.find('**/+Camera')
lens = cam.node().getLens()
@ -410,19 +404,18 @@ class ShowBase:
for i in range(chanConfig.getNumDrs()):
self.groupList.append(chanConfig.getGroupMembership(i))
# Set the default camera
# Set the default camera and cam
if self.camera == None:
self.camera = self.cameraList[0]
if self.cam == None:
self.cam = self.camList[0]
# If you need to get a handle to the camera node itself,
# use self.camNode.
self.camNode = self.cam.node()
# If you need to adjust camera parameters, like fov or
# near/far clipping planes, use self.camLens.
self.camLens = self.camNode.getLens()
def getAlt(self):
return base.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.alt())
@ -536,7 +529,7 @@ class ShowBase:
# traverse the data graph. This reads all the control
# inputs (from the mouse and keyboard, for instance) and also
# directly acts upon them (for instance, to move the avatar).
traverseDataGraph(self.dataRootNode)
self.dgTrav.traverse(self.dataRootNode)
return Task.cont
def igloop(self, state):
@ -545,14 +538,10 @@ class ShowBase:
if self.cTrav:
self.cTrav.traverse(self.render)
if self.appTrav:
self.appTrav.traverse(self.render.getTopNode())
self.appTrav.traverse(self.render)
# Finally, render the frame.
for win in self.winList:
win.renderAndUpdate()
# The clock needs to be ticked once per frame.
globalClock.tick()
self.graphicsEngine.renderFrame()
# Lerp stuff needs this event, and it must be generated in
# C++, not in Python.
@ -575,37 +564,50 @@ class ShowBase:
self.eventMgr.shutdown()
def toggleBackface(self):
return toggleBackface(self.render.arc())
if self.backfaceCullingEnabled:
self.backfaceCullingOff()
else:
self.backfaceCullingOn()
def backfaceCullingOn(self):
if self.toggleBackface():
self.toggleBackface()
if not self.backfaceCullingEnabled:
self.render.setTwoSided(0)
self.backfaceCullingEnabled = 1
def backfaceCullingOff(self):
if not self.toggleBackface():
self.toggleBackface()
if self.backfaceCullingEnabled:
self.render.setTwoSided(1)
self.backfaceCullingEnabled = 0
def toggleTexture(self):
return toggleTexture(self.render.arc())
if self.textureEnabled:
self.textureOff()
else:
self.textureOn()
def textureOn(self):
if not self.toggleTexture():
self.toggleTexture()
self.render.clearTexture()
self.textureEnabled = 1
def textureOff(self):
if self.toggleTexture():
self.toggleTexture()
self.render.setTextureOff(100)
self.textureEnabled = 0
def toggleWireframe(self):
return toggleWireframe(self.render.arc())
if self.wireframeEnabled:
self.wireframeOff()
else:
self.wireframeOn()
def wireframeOn(self):
if not self.toggleWireframe():
self.toggleWireframe()
self.render.setRenderModeWireframe(100);
self.render.setTwoSided(1);
self.wireframeEnabled = 1
def wireframeOff(self):
if self.toggleWireframe():
self.toggleWireframe()
self.render.clearRenderMode()
render.setTwoSided(not self.backfaceCullingEnabled)
self.wireframeEnabled = 0
def disableMouse(self):
"""
@ -628,39 +630,37 @@ class ShowBase:
"""
self.mouse2cam.reparentTo(self.mouseInterface)
def setMouseOnArc(self, newArc):
self.mouse2cam.node().setArc(newArc)
def setMouseOnNode(self, newNode):
self.mouse2cam.node().setNode(newNode)
def useDrive(self):
"""
Switch mouse action to drive mode
"""
# Get rid of the trackball
self.trackball.reparentTo(self.dataUnused)
self.mouseInterface.reparentTo(self.dataUnused)
# Update the mouseInterface to point to the drive
self.mouseInterface = self.drive
self.mouseInterfaceNode = self.mouseInterface.node()
self.drive.node().reset()
# Hookup the drive to the camera. Make sure it is first in
# the list of children of the mouseValve.
self.drive.reparentTo(self.mouseValve, 0)
self.mouse2cam.reparentTo(self.drive)
# Hookup the drive to the camera.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.mouse2cam.reparentTo(self.mouseInterface)
# Set the height to a good eyeheight
self.drive.node().setZ(4.0)
self.mouseInterfaceNode.reset()
self.mouseInterfaceNode.setZ(4.0)
def useTrackball(self):
"""
Switch mouse action to trackball mode
"""
# Get rid of the drive
self.drive.reparentTo(self.dataUnused)
self.mouseInterface.reparentTo(self.dataUnused)
# Update the mouseInterface to point to the trackball
self.mouseInterface = self.trackball
self.mouseInterfaceNode = self.mouseInterface.node()
# Hookup the trackball to the camera. Make sure it is first
# in the list of children of the mouseValve.
self.trackball.reparentTo(self.mouseValve, 0)
self.mouse2cam.reparentTo(self.trackball)
# Hookup the trackball to the camera.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.mouse2cam.reparentTo(self.mouseInterface)
def oobe(self):
"""
@ -698,25 +698,17 @@ class ShowBase:
self.oobeLens.setAspectRatio(self.aspectRatio)
self.oobeLens.setNearFar(0.1, 10000.0)
self.oobeLens.setFov(52.0)
self.oobeControl = DataValve.Control()
self.mouseValve.node().setControl(1, self.oobeControl)
self.oobeTrackball = self.mouseValve.attachNewNode(Trackball('oobeTrackball'), 1)
self.oobe2cam = self.oobeTrackball.attachNewNode(Transform2SG('oobe2cam'))
self.oobe2cam.node().setArc(self.oobeCameraTrackball.arc())
self.oobeButtonEventsType = TypeRegistry.ptr().findType('ButtonEvents_ButtonEventDataTransition')
self.oobeTrackball = self.dataUnused.attachNewNode(Trackball('oobeTrackball'), 1)
self.oobe2cam = self.oobeTrackball.attachNewNode(Transform2SG('oobe2cam'))
self.oobe2cam.node().setNode(self.oobeCameraTrackball.node())
self.oobeVis = loader.loadModelOnce('models/misc/camera')
if self.oobeVis:
self.oobeVis.arc().setFinal(1)
self.oobeVis.node().setFinal(1)
self.oobeCullFrustum = None
self.oobeCullFrustumVis = None
# Make sure the MouseValve is monitoring the Control key.
mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
mods.addButton(KeyboardButton.control())
self.mouseValve.node().setModifierButtons(mods)
if self.oobeMode:
# Disable OOBE mode.
@ -724,35 +716,28 @@ class ShowBase:
# First, disable OOBE cull mode.
self.oobeCull()
self.oobeControl.setOff()
self.mouseControl.setOn()
if self.oobeVis:
self.oobeVis.reparentTo(self.hidden)
# Restore the mouse interface node.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.oobeTrackball.reparentTo(self.dataUnused)
self.cam.reparentTo(self.camera)
self.camNode.setLens(self.camLens)
self.oobeCamera.reparentTo(self.hidden)
self.oobeMode = 0
else:
# Enable OOBE mode.
mods = ModifierButtons(self.mouseValve.node().getModifierButtons())
# We're in OOBE control mode without the control key.
mods.allButtonsUp()
self.oobeControl.setButtons(mods)
# We're in traditional control mode with the control key.
mods.buttonDown(KeyboardButton.control())
self.mouseControl.setButtons(mods)
# However, keyboard buttons always make it through to the
# traditional controller, regardless of the control key.
self.mouseValve.node().setFineControl(0, self.oobeButtonEventsType, self.onControl)
# Make oobeCamera be a sibling of wherever camera is now.
cameraParent = self.camera.getParent()
self.oobeCamera.reparentTo(cameraParent)
self.oobeCamera.clearMat()
# Move aside the current mouse interface node and put the
# oobeTrackball in its place.
self.mouseInterface.reparentTo(self.dataUnused)
self.oobeTrackball.reparentTo(self.mouseWatcher)
# Set our initial OOB position to be just behind the camera.
mat = Mat4.translateMat(0, -10, 3) * self.camera.getMat(cameraParent)
mat.invertInPlace()
@ -793,18 +778,18 @@ class ShowBase:
# Assign each DisplayRegion shared by the camera to use
# this cull frustum.
numDrs = self.camNode.getNumDrs()
for d in range(0, numDrs):
dr = self.camNode.getDr(d)
numDisplayRegions = self.camNode.getNumDisplayRegions()
for d in range(0, numDisplayRegions):
dr = self.camNode.getDisplayRegion(d)
dr.setCullFrustum(pnode)
else:
# Disable OOBE culling.
# Assign each DisplayRegion shared by the camera to use
# the default cull frustum, the camera itself.
numDrs = self.camNode.getNumDrs()
for d in range(0, numDrs):
dr = self.camNode.getDr(d)
numDisplayRegions = self.camNode.getNumDisplayRegions()
for d in range(0, numDisplayRegions):
dr = self.camNode.getDisplayRegion(d)
dr.setCullFrustum(self.camNode)
self.oobeCullFrustum.removeNode()

View File

@ -1,10 +1,6 @@
"""instantiate global ShowBase object"""
import UsePgraph
if UsePgraph.use:
from qpShowBase import *
else:
from ShowBase import *
from ShowBase import *
# Create the showbase instance
ShowBase()

View File

@ -1,6 +0,0 @@
# Set this to 1 to use the experimental pgraph code. This must be set
# at genPyCode time as well as at run time.
use = 1

View File

@ -1,887 +0,0 @@
# This module redefines the builtin import function with one
# that prints out every import it does in a hierarchical form
# Annoying and very noisy, but sometimes useful
# import VerboseImport
from PandaModules import *
from DirectNotifyGlobal import *
from MessengerGlobal import *
from TaskManagerGlobal import *
from EventManagerGlobal import *
from PythonUtil import *
from ParticleManagerGlobal import *
from PhysicsManagerGlobal import *
import Task
import EventManager
import math
import sys
import Loader
import time
import FSM
import State
import __builtin__
__builtin__.FADE_SORT_INDEX = 1000
__builtin__.NO_FADE_SORT_INDEX = 2000
globalClock = ClockObject.getGlobalClock()
class ShowBase:
notify = directNotify.newCategory("ShowBase")
def __init__(self):
# Get the dconfig object
self.config = ConfigConfigureGetConfigConfigShowbase
# Store dconfig variables
self.wantTk = self.config.GetBool('want-tk', 0)
self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
self.musicActive = self.config.GetBool('audio-music-active', 1)
self.wantFog = self.config.GetBool('want-fog', 1)
self.screenshotExtension = self.config.GetString('screenshot-extension', 'jpg')
self.musicManager = None
self.musicManagerIsValid = None
self.sfxManager = None
self.sfxManagerIsValid = None
self.wantDIRECT = self.config.GetBool('want-directtools', 0)
self.wantStats = self.config.GetBool('want-stats', 0)
taskMgr.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
taskMgr.extendedExceptions = self.config.GetBool('extended-exceptions', 0)
taskMgr.pStatsTasks = self.config.GetBool('pstats-tasks', 0)
# Set up the TaskManager to reset the PStats clock back
# whenever we resume from a pause. This callback function is
# a little hacky, but we can't call it directly from within
# the TaskManager because he doesn't know about PStats (and
# has to run before libpanda is even loaded).
taskMgr.resumeFunc = PStatClient.resumeAfterPause
fsmRedefine = self.config.GetBool('fsm-redefine', 0)
State.FsmRedefine = fsmRedefine
self.hidden = NodePath('hidden')
# We need a graphics engine to manage the actual rendering.
self.graphicsEngine = GraphicsEngine()
self.setupRender()
self.setupRender2d()
self.setupDataGraph()
# This is a placeholder for a CollisionTraverser. If someone
# stores a CollisionTraverser pointer here, we'll traverse it
# in the igloop task.
self.cTrav = 0
# Ditto for an AppTraverser.
self.appTrav = 0
# This is the DataGraph traverser, which we might as well
# create now.
self.dgTrav = DataGraphTraverser()
# base.win is the main, or only window; base.winList is a list of
# *all* windows. Similarly with base.pipeList and base.camList.
self.win = None
self.winList = []
self.pipe = None
self.pipeList = []
self.cam = None
self.camList = []
self.camNode = None
self.camLens = None
self.camera = None
self.cameraList = []
self.groupList = []
self.camera2d = self.render2d.attachNewNode('camera2d')
# Now that we've set up the window structures, assign an exitfunc.
self.oldexitfunc = getattr(sys, 'exitfunc', None)
sys.exitfunc = self.exitfunc
# Open the default rendering window.
if self.config.GetBool('open-default-window', 1):
self.openWindow()
self.setupMouse(self.win)
self.makeCamera2d(self.win, -1, 1, -1, 1)
self.loader = Loader.Loader(self)
self.eventMgr = eventMgr
self.messenger = messenger
self.taskMgr = taskMgr
# Particle manager
self.particleMgr = particleMgr
self.particleMgr.setFrameStepping(1)
self.particleMgrEnabled = 0
# Physics manager
self.physicsMgr = physicsMgr
integrator = LinearEulerIntegrator()
self.physicsMgr.attachLinearIntegrator(integrator)
self.physicsMgrEnabled = 0
self.physicsMgrAngular = 0
self.createAudioManager()
self.createStats()
self.AppHasAudioFocus = 1
__builtin__.base = self
__builtin__.render2d = self.render2d
__builtin__.aspect2d = self.aspect2d
__builtin__.render = self.render
__builtin__.hidden = self.hidden
__builtin__.camera = self.camera
__builtin__.loader = self.loader
__builtin__.taskMgr = self.taskMgr
__builtin__.eventMgr = self.eventMgr
__builtin__.messenger = self.messenger
__builtin__.config = self.config
__builtin__.run = self.run
__builtin__.ostream = Notify.out()
__builtin__.directNotify = directNotify
# Transition effects (fade, iris, etc)
import Transitions
self.transitions = Transitions.Transitions(self.loader)
# Tk
if self.wantTk:
import TkGlobal
if self.wantDIRECT:
import DirectSession
direct.enable()
else:
__builtin__.direct = self.direct = None
self.restart()
def exitfunc(self):
"""exitfunc(self)
This should be assigned to sys.exitfunc to be called just
before Python shutdown. It guarantees that the Panda window
is closed cleanly, so that we free system resources, restore
the desktop and keyboard functionality, etc.
"""
for win in self.winList:
win.closeWindow()
del self.win
del self.winList
del self.pipe
if self.oldexitfunc:
self.oldexitfunc()
def openWindow(self):
"""openWindow(self)
Invokes ChanConfig to create a window and adds it to the list
of windows that are to be updated every frame.
"""
if self.pipe == None:
self.pipe = makeGraphicsPipe()
self.pipeList.append(self.pipe)
chanConfig = qpmakeGraphicsWindow(self.pipe, self.render)
win = chanConfig.getWin()
if self.win == None:
self.win = win
self.winList.append(win)
self.graphicsEngine.addWindow(win)
self.getCameras(chanConfig)
def setupRender(self):
"""setupRender(self)
Creates the render scene graph, the primary scene graph for
rendering 3-d geometry.
"""
self.render = NodePath('render')
self.render.setTwoSided(0)
self.backfaceCullingEnabled = 1
self.textureEnabled = 1
self.wireframeEnabled = 0
def setupRender2d(self):
"""setupRender2d(self)
Creates the render2d scene graph, the primary scene graph for
2-d objects and gui elements that are superimposed over the
3-d geometry in the window.
"""
self.render2d = NodePath('render2d')
# Set up some overrides to turn off certain properties which
# we probably won't need for 2-d objects.
# It's particularly important to turn off the depth test,
# since we'll be keeping the same depth buffer already filled
# by the previously-drawn 3-d scene--we don't want to pay for
# a clear operation, but we also don't want to collide with
# that depth buffer.
dt = DepthTestAttrib.make(DepthTestAttrib.MNone)
dw = DepthWriteAttrib.make(DepthWriteAttrib.MOff)
#lt = LightTransition.allOff()
self.render2d.node().setAttrib(dt, 1)
self.render2d.node().setAttrib(dw, 1)
#self.render2d.node().setAttrib(lt, 1)
self.render2d.setMaterialOff(1)
self.render2d.setTwoSided(1, 1)
# The normal 2-d layer has an aspect ratio that matches the
# window, but its coordinate system is square. This means
# anything we parent to render2d gets stretched. For things
# where that makes a difference, we set up aspect2d, which
# scales things back to the right aspect ratio.
# For now, we assume that the window will have an aspect ratio
# matching that of a traditional PC screen (w / h) = (4 / 3)
self.aspectRatio = self.config.GetFloat('aspect-ratio', (4.0 / 3.0))
self.aspect2d = self.render2d.attachNewNode(PGTop("aspect2d"))
self.aspect2d.setScale(1.0 / self.aspectRatio, 1.0, 1.0)
# It's important to know the bounds of the aspect2d screen.
self.a2dTop = 1.0
self.a2dBottom = -1.0
self.a2dLeft = -self.aspectRatio
self.a2dRight = self.aspectRatio
def makeCamera2d(self, win, left, right, bottom, top):
"""makeCamera2d(self)
Makes a new camera2d associated with the indicated window, and
assigns it to render the indicated subrectangle of render2d.
"""
# First, we need to make a new layer on the window.
chan = win.getChannel(0)
layer = chan.makeLayer()
# And make a display region to cover the whole layer.
dr = layer.makeDisplayRegion()
# Now make a new Camera node.
cam2dNode = Camera('cam2d')
lens = OrthographicLens()
lens.setFilmSize(right - left, top - bottom)
lens.setFilmOffset((right + left) / 2.0, (top + bottom) / 2.0)
lens.setNearFar(-1000, 1000)
cam2dNode.setLens(lens)
cam2dNode.setScene(self.render2d)
camera2d = self.camera2d.attachNewNode(cam2dNode)
dr.setCamera(camera2d)
return camera2d
def setupDataGraph(self):
"""setupDataGraph(self)
Creates the data graph and populates it with the basic input
devices.
"""
self.dataRoot = NodePath('dataRoot')
# Cache the node so we do not ask for it every frame
self.dataRootNode = self.dataRoot.node()
self.dataUnused = NodePath('dataUnused')
def setupMouse(self, win):
"""setupMouse(self, win)
Creates the structures necessary to monitor the mouse input,
using the indicated window. This should only be called once
per application.
"""
# We create both a MouseAndKeyboard object and a MouseWatcher object
# for the window. The MouseAndKeyboard generates mouse events and
# mouse button/keyboard events; the MouseWatcher passes them through
# unchanged when the mouse is not over a 2-d button, and passes
# nothing through when the mouse *is* over a 2-d button. Therefore,
# objects that don't want to get events when the mouse is over a
# button, like the driveInterface, should be parented to
# mouseWatcher, while objects that want events in all cases, like the
# chat interface, should be parented to mak.
self.mak = self.dataRoot.attachNewNode(MouseAndKeyboard(win, 0, 'mak'))
self.mouseWatcherNode = MouseWatcher('mouseWatcher')
self.mouseWatcher = self.mak.attachNewNode(self.mouseWatcherNode)
mb = self.mouseWatcherNode.getModifierButtons()
mb.addButton(KeyboardButton.shift())
mb.addButton(KeyboardButton.control())
mb.addButton(KeyboardButton.alt())
self.mouseWatcherNode.setModifierButtons(mb)
# Now we have the main trackball & drive interfaces.
# useTrackball() and useDrive() switch these in and out; only
# one is in use at a given time.
self.trackball = self.dataUnused.attachNewNode(Trackball('trackball'))
self.drive = self.dataUnused.attachNewNode(DriveInterface('drive'))
self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
self.mouse2cam.node().setNode(self.camera.node())
# The default is trackball mode, which is more convenient for
# ad-hoc development in Python using ShowBase. Applications
# can explicitly call base.useDrive() if they prefer a drive
# interface.
self.mouseInterface = self.trackball
self.useTrackball()
# A ButtonThrower to generate events from the mouse and
# keyboard buttons as they are pressed.
self.buttonThrower = self.mouseWatcher.attachNewNode(ButtonThrower('buttons'))
# Specialize the events based on whether the modifier keys are
# being held down.
mods = ModifierButtons()
mods.addButton(KeyboardButton.shift())
mods.addButton(KeyboardButton.control())
mods.addButton(KeyboardButton.alt())
self.buttonThrower.node().setModifierButtons(mods)
# Tell the gui system about our new mouse watcher.
self.aspect2d.node().setMouseWatcher(self.mouseWatcherNode)
self.mouseWatcherNode.addRegion(PGMouseWatcherBackground())
def enableSoftwareMousePointer(self):
"""enableSoftwareMousePointer(self)
Creates some geometry and parents it to render2d to show
the currently-known mouse position. Useful if the mouse
pointer is invisible for some reason.
"""
mouseViz = render2d.attachNewNode('mouseViz')
lilsmiley = loader.loadModel('lilsmiley')
lilsmiley.reparentTo(mouseViz)
# Scale the smiley face to 32x32 pixels.
lilsmiley.setScale(32.0 / self.win.getHeight() / self.aspectRatio, 1.0, 32.0 / self.win.getHeight())
#self.mouseWatcherNode.setGeometry(mouseViz)
def getCameras(self, chanConfig):
"""
getCameras(self, chanConfig)
Extracts the camera(s) out of the ChanConfig record, parents
them all to base.camera, and adds them to base.cameraList.
"""
# cameraList is a list of camera group nodes. There may
# be more than one display region/camera node beneath each
# one.
for i in range(chanConfig.getNumGroups()):
camera = self.render.attachNewNode(chanConfig.getGroupNode(i))
cam = camera.find('**/+Camera')
lens = cam.node().getLens()
# Enforce our expected aspect ratio, overriding whatever
# nonsense ChanConfig put in there.
lens.setAspectRatio(self.aspectRatio)
self.cameraList.append(camera)
self.camList.append(cam)
# this is how we know which display region cameras belong to which
# camera group. display region i belongs to group self.groupList[i]
for i in range(chanConfig.getNumDrs()):
self.groupList.append(chanConfig.getGroupMembership(i))
# Set the default camera and cam
if self.camera == None:
self.camera = self.cameraList[0]
if self.cam == None:
self.cam = self.camList[0]
# If you need to get a handle to the camera node itself,
# use self.camNode.
self.camNode = self.cam.node()
# If you need to adjust camera parameters, like fov or
# near/far clipping planes, use self.camLens.
self.camLens = self.camNode.getLens()
def getAlt(self):
return base.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.alt())
def getShift(self):
return base.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.shift())
def getControl(self):
return base.mouseWatcherNode.getModifierButtons().isDown(
KeyboardButton.control())
def addAngularIntegrator(self):
"""addAngularIntegrator(self)"""
if (self.physicsMgrAngular == 0):
self.physicsMgrAngular = 1
integrator = AngularEulerIntegrator()
self.physicsMgr.attachAngularIntegrator(integrator)
def enableParticles(self):
"""enableParticles(self)"""
self.particleMgrEnabled = 1
self.physicsMgrEnabled = 1
self.taskMgr.remove('manager-update')
self.taskMgr.add(self.updateManagers, 'manager-update')
def disableParticles(self):
"""enableParticles(self)"""
self.particleMgrEnabled = 0
self.physicsMgrEnabled = 0
self.taskMgr.remove('manager-update')
def toggleParticles(self):
if self.particleMgrEnabled == 0:
self.enableParticles()
else:
self.disableParticles()
def isParticleMgrEnabled(self):
return self.particleMgrEnabled
def isPhysicsMgrEnabled(self):
return self.physicsMgrEnabled
def updateManagers(self, state):
"""updateManagers(self)"""
dt = min(globalClock.getDt(), 0.1)
if (self.particleMgrEnabled == 1):
self.particleMgr.doParticles(dt)
if (self.physicsMgrEnabled == 1):
self.physicsMgr.doPhysics(dt)
return Task.cont
def createStats(self):
# You must specify a pstats-host in your configrc
# The default is localhost
if self.wantStats:
PStatClient.connect()
def createAudioManager(self):
self.sfxManager = AudioManager.createAudioManager()
self.sfxManagerIsValid=self.sfxManager!=None \
and self.sfxManager.isValid()
if self.sfxManagerIsValid:
self.sfxManager.setActive(self.sfxActive)
self.musicManager = AudioManager.createAudioManager()
self.musicManagerIsValid=self.musicManager!=None \
and self.musicManager.isValid()
if self.musicManagerIsValid:
self.musicManager.setActive(self.musicActive)
# Turn down the music globally
# Eventually we may want to control this in the options page
self.musicManager.setVolume(0.7)
def loadSfx(self, name):
if (name):
sound=self.sfxManager.getSound(name)
if sound == None:
self.notify.warning("Could not load sound file %s." % name)
return sound
def loadMusic(self, name):
if (name):
sound=self.musicManager.getSound(name)
if sound == None:
self.notify.warning("Could not load music file %s." % name)
return sound
def playSfx(self, sfx, looping = 0, interupt = 1, volume = None,
time = 0.):
if sfx:
if volume != None:
sfx.setVolume(volume)
if interupt or (sfx.status() != AudioSound.PLAYING):
sfx.setTime(time)
sfx.setLoop(looping)
sfx.play()
def playMusic(self, music, looping = 0, interupt = 1, volume = None,
time = 0.0):
if music:
if volume != None:
music.setVolume(volume)
if interupt or (music.status() != AudioSound.PLAYING):
music.setTime(time)
music.setLoop(looping)
music.play()
def dataloop(self, state):
# traverse the data graph. This reads all the control
# inputs (from the mouse and keyboard, for instance) and also
# directly acts upon them (for instance, to move the avatar).
self.dgTrav.traverse(self.dataRootNode)
return Task.cont
def igloop(self, state):
# run the collision traversal if we have a
# CollisionTraverser set.
if self.cTrav:
self.cTrav.traverse(self.render)
if self.appTrav:
self.appTrav.traverse(self.render)
# Finally, render the frame.
self.graphicsEngine.renderFrame()
# Lerp stuff needs this event, and it must be generated in
# C++, not in Python.
throwNewFrame()
return Task.cont
def restart(self):
self.shutdown()
# give the igloop task a reasonably "late" priority,
# so that it will get run after most tasks
self.taskMgr.add(self.igloop, 'igloop', priority = 50)
# give the dataloop task a reasonably "early" priority,
# so that it will get run before most tasks
self.taskMgr.add(self.dataloop, 'dataloop', priority = -50)
self.eventMgr.restart()
def shutdown(self):
self.taskMgr.remove('igloop')
self.taskMgr.remove('dataloop')
self.eventMgr.shutdown()
def toggleBackface(self):
if self.backfaceCullingEnabled:
self.backfaceCullingOff()
else:
self.backfaceCullingOn()
def backfaceCullingOn(self):
if not self.backfaceCullingEnabled:
self.render.setTwoSided(0)
self.backfaceCullingEnabled = 1
def backfaceCullingOff(self):
if self.backfaceCullingEnabled:
self.render.setTwoSided(1)
self.backfaceCullingEnabled = 0
def toggleTexture(self):
if self.textureEnabled:
self.textureOff()
else:
self.textureOn()
def textureOn(self):
self.render.clearTexture()
self.textureEnabled = 1
def textureOff(self):
self.render.setTextureOff(100)
self.textureEnabled = 0
def toggleWireframe(self):
if self.wireframeEnabled:
self.wireframeOff()
else:
self.wireframeOn()
def wireframeOn(self):
self.render.setRenderModeWireframe(100);
self.render.setTwoSided(1);
self.wireframeEnabled = 1
def wireframeOff(self):
self.render.clearRenderMode()
render.setTwoSided(not self.backfaceCullingEnabled)
self.wireframeEnabled = 0
def disableMouse(self):
"""
Temporarily disable the mouse control of the camera, either
via the drive interface or the trackball, whichever is
currently in use.
"""
# We don't reparent the drive interface or the trackball;
# whichever one was there before will remain in the data graph
# and active. This way they won't lose button events while
# the mouse is disabled. However, we do move the mouse2cam
# object out of there, so we won't be updating the camera any
# more.
self.mouse2cam.reparentTo(self.dataUnused)
def enableMouse(self):
"""
Reverse the effect of a previous call to disableMouse().
useDrive() also implicitly enables the mouse.
"""
self.mouse2cam.reparentTo(self.mouseInterface)
def setMouseOnNode(self, newNode):
self.mouse2cam.node().setNode(newNode)
def useDrive(self):
"""
Switch mouse action to drive mode
"""
# Get rid of the trackball
self.mouseInterface.reparentTo(self.dataUnused)
# Update the mouseInterface to point to the drive
self.mouseInterface = self.drive
self.mouseInterfaceNode = self.mouseInterface.node()
# Hookup the drive to the camera.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.mouse2cam.reparentTo(self.mouseInterface)
# Set the height to a good eyeheight
self.mouseInterfaceNode.reset()
self.mouseInterfaceNode.setZ(4.0)
def useTrackball(self):
"""
Switch mouse action to trackball mode
"""
# Get rid of the drive
self.mouseInterface.reparentTo(self.dataUnused)
# Update the mouseInterface to point to the trackball
self.mouseInterface = self.trackball
self.mouseInterfaceNode = self.mouseInterface.node()
# Hookup the trackball to the camera.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.mouse2cam.reparentTo(self.mouseInterface)
def oobe(self):
"""
Enable a special "out-of-body experience" mouse-interface
mode. This can be used when a "god" camera is needed; it
moves the camera node out from under its normal node and sets
the world up in trackball state. Button events are still sent
to the normal mouse action node (e.g. the DriveInterface), and
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
the existing mouse action to a trackball interface. In fact,
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
mode is in effect.
This is a toggle; the second time this function is called, it
disables the mode.
"""
# If oobeMode was never set, set it to false and create the
# structures we need to implement OOBE.
try:
self.oobeMode
except:
self.oobeMode = 0
self.oobeCamera = self.hidden.attachNewNode('oobeCamera')
self.oobeCameraTrackball = self.oobeCamera.attachNewNode('oobeCameraTrackball')
self.oobeLens = PerspectiveLens()
self.oobeLens.setAspectRatio(self.aspectRatio)
self.oobeLens.setNearFar(0.1, 10000.0)
self.oobeLens.setFov(52.0)
self.oobeTrackball = self.dataUnused.attachNewNode(Trackball('oobeTrackball'), 1)
self.oobe2cam = self.oobeTrackball.attachNewNode(Transform2SG('oobe2cam'))
self.oobe2cam.node().setNode(self.oobeCameraTrackball.node())
self.oobeVis = loader.loadModelOnce('models/misc/camera')
if self.oobeVis:
self.oobeVis.node().setFinal(1)
self.oobeCullFrustum = None
self.oobeCullFrustumVis = None
if self.oobeMode:
# Disable OOBE mode.
if self.oobeCullFrustum != None:
# First, disable OOBE cull mode.
self.oobeCull()
if self.oobeVis:
self.oobeVis.reparentTo(self.hidden)
# Restore the mouse interface node.
self.mouseInterface.reparentTo(self.mouseWatcher)
self.oobeTrackball.reparentTo(self.dataUnused)
self.cam.reparentTo(self.camera)
self.camNode.setLens(self.camLens)
self.oobeCamera.reparentTo(self.hidden)
self.oobeMode = 0
else:
# Make oobeCamera be a sibling of wherever camera is now.
cameraParent = self.camera.getParent()
self.oobeCamera.reparentTo(cameraParent)
self.oobeCamera.clearMat()
# Move aside the current mouse interface node and put the
# oobeTrackball in its place.
self.mouseInterface.reparentTo(self.dataUnused)
self.oobeTrackball.reparentTo(self.mouseWatcher)
# Set our initial OOB position to be just behind the camera.
mat = Mat4.translateMat(0, -10, 3) * self.camera.getMat(cameraParent)
mat.invertInPlace()
self.oobeTrackball.node().setMat(mat)
self.cam.reparentTo(self.oobeCameraTrackball)
self.camNode.setLens(self.oobeLens)
if self.oobeVis:
self.oobeVis.reparentTo(self.camera)
self.oobeMode = 1
def oobeCull(self):
"""
While in OOBE mode (see above), cull the viewing frustum as if
it were still attached to our original camera. This allows us
to visualize the effectiveness of our bounding volumes.
"""
# First, make sure OOBE mode is enabled.
try:
if not self.oobeMode:
self.oobe()
except:
self.oobe()
if self.oobeCullFrustum == None:
# Enable OOBE culling.
pnode = LensNode('oobeCull')
pnode.setLens(self.camLens)
self.oobeCullFrustum = self.camera.attachNewNode(pnode)
# Create a visible representation of the frustum.
geom = self.camLens.makeGeometry()
if geom != None:
gn = GeomNode('frustum')
gn.addGeom(geom)
self.oobeCullFrustumVis = self.oobeVis.attachNewNode(gn)
# Assign each DisplayRegion shared by the camera to use
# this cull frustum.
numDisplayRegions = self.camNode.getNumDisplayRegions()
for d in range(0, numDisplayRegions):
dr = self.camNode.getDisplayRegion(d)
dr.setCullFrustum(pnode)
else:
# Disable OOBE culling.
# Assign each DisplayRegion shared by the camera to use
# the default cull frustum, the camera itself.
numDisplayRegions = self.camNode.getNumDisplayRegions()
for d in range(0, numDisplayRegions):
dr = self.camNode.getDisplayRegion(d)
dr.setCullFrustum(self.camNode)
self.oobeCullFrustum.removeNode()
self.oobeCullFrustum = None
if self.oobeCullFrustumVis != None:
self.oobeCullFrustumVis.removeNode()
self.oobeCullFrustumVis = None
def screenshot(self, namePrefix='screenshot'):
# Get the current date and time to uniquify the image (down to the second)
date = time.ctime(time.time())
# Get the current frame count to uniqify it even more
frameCount = globalClock.getFrameCount()
# Replace spaces with dashes because unix does not like spaces in the filename
date = date.replace(' ', '-')
date = date.replace(':', '-')
imageName = ('%s-%s-%d.%s' % (namePrefix, date, frameCount, self.screenshotExtension))
self.notify.info("Taking screenshot: " + imageName)
takeSnapshot(self.win, imageName)
def movie(self, namePrefix = 'movie', duration = 1.0, fps = 30,
format = 'rgb', sd = 4):
"""
movie(namePrefix = 'movie', duration=1.0, fps=30, format='rgb', sd=4)
Spawn a task to capture a movie using the takeSnapshot function.
- namePrefix will be used to form output file names (can include
path information (e.g. 'I:/beta/frames/myMovie')
- duration is the length of the movie in seconds
- fps is the frame rate of the resulting movie
- format specifies output file format (e.g. rgb, bmp)
- sd specifies number of significant digits for frame count in the
output file name (e.g. if sd = 4, movie_0001.rgb)
"""
globalClock.setMode(ClockObject.MNonRealTime)
globalClock.setDt(1.0/float(fps))
t = taskMgr.add(self._movieTask, namePrefix + '_task')
t.endT = globalClock.getFrameTime() + duration
t.frameIndex = 1
t.outputString = namePrefix + '_%0' + `sd` + 'd.' + format
t.uponDeath = lambda state: globalClock.setMode(ClockObject.MNormal)
def _movieTask(self, state):
currT = globalClock.getFrameTime()
if currT >= state.endT:
return Task.done
else:
frameName = state.outputString % state.frameIndex
self.notify.info("Capturing frame: " + frameName)
takeSnapshot(self.win, frameName )
state.frameIndex += 1
return Task.cont
# these are meant to be called in response to a user request
def EnableMusic(self, bEnableMusic):
# dont setActive(1) if no audiofocus
if self.AppHasAudioFocus and self.musicManagerIsValid:
self.musicManager.setActive(bEnableMusic)
self.musicActive = bEnableMusic
if bEnableMusic:
self.notify.debug("Enabling music")
else:
self.notify.debug("Disabling music")
def EnableSoundEffects(self, bEnableSoundEffects):
# dont setActive(1) if no audiofocus
if self.AppHasAudioFocus and self.sfxManagerIsValid:
self.sfxManager.setActive(bEnableSoundEffects)
self.sfxActive=bEnableSoundEffects
if bEnableSoundEffects:
self.notify.debug("Enabling sound effects")
else:
self.notify.debug("Disabling sound effects")
# these are meant to be called by the sw when app loses audio focus (switched out)
def DisableAudio(self):
self.AppHasAudioFocus = 0
if self.sfxManagerIsValid:
self.sfxManager.setActive(0)
if self.musicManagerIsValid:
self.musicManager.setActive(0)
self.notify.debug("Disabling audio")
def EnableAudio(self):
self.AppHasAudioFocus = 1
if self.sfxManagerIsValid:
self.sfxManager.setActive(self.sfxActive)
if self.musicManagerIsValid:
self.musicManager.setActive(self.musicActive)
self.notify.debug("Enabling audio")
def run(self):
self.taskMgr.run()

View File

@ -24,7 +24,7 @@
#include "chancfg.h"
#include "renderBuffer.h"
#include "get_config_path.h"
#include "qpcamera.h"
#include "camera.h"
ConfigureDef(config_showbase);
ConfigureFn(config_showbase) {
@ -65,8 +65,8 @@ make_graphics_pipe() {
return main_pipe;
}
qpChanConfig
qpmake_graphics_window(GraphicsPipe *pipe, const qpNodePath &render) {
ChanConfig
make_graphics_window(GraphicsPipe *pipe, const NodePath &render) {
PT(GraphicsWindow) main_win;
ChanCfgOverrides override;
@ -78,7 +78,7 @@ qpmake_graphics_window(GraphicsPipe *pipe, const qpNodePath &render) {
override.setField(ChanCfgOverrides::Title, title);
std::string conf = config_showbase.GetString("chan-config", chan_config);
qpChanConfig chan_config(pipe, conf, render, override);
ChanConfig chan_config(pipe, conf, render, override);
main_win = chan_config.get_win();
assert(main_win != (GraphicsWindow*)0L);

View File

@ -28,7 +28,7 @@
#include "pointerTo.h"
#include "dconfig.h"
#include "dSearchPath.h"
#include "qpnodePath.h"
#include "nodePath.h"
#include "chancfg.h"
ConfigureDecl(config_showbase, EXPCL_DIRECT, EXPTP_DIRECT);
@ -42,8 +42,8 @@ BEGIN_PUBLISH
EXPCL_DIRECT DSearchPath &get_particle_path();
EXPCL_DIRECT PT(GraphicsPipe) make_graphics_pipe();
EXPCL_DIRECT qpChanConfig
qpmake_graphics_window(GraphicsPipe *pipe, const qpNodePath &render);
EXPCL_DIRECT ChanConfig
make_graphics_window(GraphicsPipe *pipe, const NodePath &render);
EXPCL_DIRECT void throw_new_frame();

View File

@ -12,7 +12,6 @@ import Slider
import VectorWidgets
import SceneGraphExplorer
from TaskManagerPanel import TaskManagerWidget
import UsePgraph
"""
Possible to add:
@ -905,9 +904,8 @@ class DirectSessionPanel(AppShell):
def updateLightInfo(self, page = None):
# Set main lighting button
if UsePgraph.use:
self.enableLights.set(
render.node().hasAttrib(LightAttrib.getClassType()))
self.enableLights.set(
render.node().hasAttrib(LightAttrib.getClassType()))
# Set light specific info
if self.activeLight:

View File

@ -20,7 +20,7 @@
#include "bamFile.h"
#include "pandaNode.h"
#include "qpgeomNode.h"
#include "geomNode.h"
#include "dcast.h"
#include "pvector.h"
@ -230,7 +230,7 @@ list_hierarchy(PandaNode *node, int indent_level) {
}
if (_verbose_geoms && node->is_geom_node()) {
qpGeomNode *geom_node;
GeomNode *geom_node;
DCAST_INTO_V(geom_node, node);
geom_node->write_verbose(nout, indent_level);
}

View File

@ -19,8 +19,8 @@
#include "bamToEgg.h"
#include "node.h"
#include "qpLODNode.h"
#include "qpgeomNode.h"
#include "LODNode.h"
#include "geomNode.h"
#include "geom.h"
#include "geomTri.h"
#include "string_utils.h"

View File

@ -20,7 +20,7 @@
#include "config_util.h"
#include "bamFile.h"
#include "qpload_egg_file.h"
#include "load_egg_file.h"
#include "config_egg2pg.h"
#include "config_gobj.h"
#include "config_chan.h"
@ -136,7 +136,7 @@ run() {
_data.set_coordinate_system(CS_zup_right);
}
PT(PandaNode) root = qpload_egg_data(_data);
PT(PandaNode) root = load_egg_data(_data);
if (root == (PandaNode *)NULL) {
nout << "Unable to build scene graph from egg file.\n";
exit(1);

View File

@ -19,11 +19,11 @@
#include "paletteGroups.h"
#include "paletteGroup.h"
#include <indent.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include "indent.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
TypeHandle PaletteGroups::_type_handle;

View File

@ -19,13 +19,12 @@
#ifndef PALETTEGROUPS_H
#define PALETTEGROUPS_H
#include <pandatoolbase.h>
#include <typedWritable.h>
#include "pandatoolbase.h"
#include "typedWritable.h"
#include "pset.h"
class PaletteGroup;
class FactoryParams;
////////////////////////////////////////////////////////////////////
// Class : PaletteGroups

View File

@ -19,11 +19,11 @@
#ifndef PALETTIZER_H
#define PALETTIZER_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
#include "txaFile.h"
#include <typedWritable.h>
#include "typedWritable.h"
#include "pvector.h"
#include "pset.h"
@ -34,6 +34,7 @@ class EggFile;
class PaletteGroup;
class TextureImage;
class TexturePlacement;
class FactoryParams;
////////////////////////////////////////////////////////////////////
// Class : Palettizer

View File

@ -19,11 +19,11 @@
#include "textureProperties.h"
#include "palettizer.h"
#include <pnmFileType.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include "pnmFileType.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
TypeHandle TextureProperties::_type_handle;

View File

@ -19,12 +19,13 @@
#ifndef TEXTUREPROPERTIES_H
#define TEXTUREPROPERTIES_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
#include <eggTexture.h>
#include <typedWritable.h>
#include "eggTexture.h"
#include "typedWritable.h"
class PNMFileType;
class FactoryParams;
////////////////////////////////////////////////////////////////////
// Class : TextureProperties

View File

@ -20,7 +20,7 @@
#include "somethingToEggConverter.h"
#include "config_util.h"
#include "qpload_egg_file.h"
#include "load_egg_file.h"
#include "eggData.h"
TypeHandle LoaderFileTypePandatool::_type_handle;
@ -84,14 +84,14 @@ resolve_filename(Filename &path) const {
// Description:
////////////////////////////////////////////////////////////////////
PT(PandaNode) LoaderFileTypePandatool::
qpload_file(const Filename &path, bool) const {
load_file(const Filename &path, bool) const {
PT(PandaNode) result;
EggData egg_data;
_converter->set_egg_data(&egg_data, false);
if (_converter->convert_file(path)) {
egg_data.set_coordinate_system(CS_default);
result = qpload_egg_data(egg_data);
result = load_egg_data(egg_data);
}
_converter->clear_egg_data();
return result.p();

View File

@ -41,7 +41,7 @@ public:
virtual string get_extension() const;
virtual void resolve_filename(Filename &path) const;
virtual PT(PandaNode) qpload_file(const Filename &path, bool report_errors) const;
virtual PT(PandaNode) load_file(const Filename &path, bool report_errors) const;
private:
SomethingToEggConverter *_converter;