mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Fixes to make compatible with new panda
This commit is contained in:
parent
ba517a3317
commit
ce32c8c748
@ -1,14 +1,10 @@
|
||||
"""ClusterClient: Master for mutlipiping or PC clusters. """
|
||||
|
||||
from PandaModules import *
|
||||
from TaskManagerGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
import Task
|
||||
import DirectNotifyGlobal
|
||||
import Datagram
|
||||
import DirectObject
|
||||
from ClusterMsgs import *
|
||||
import time
|
||||
import DirectNotifyGlobal
|
||||
import DirectObject
|
||||
import Task
|
||||
|
||||
class ClusterConfigItem:
|
||||
def __init__(self, serverFunction, serverName, port):
|
||||
@ -79,10 +75,12 @@ class DisplayConnection:
|
||||
|
||||
# the following should only be called by a synchronized cluster manger
|
||||
def getSwapReady(self):
|
||||
datagram = self.msgHandler.blockingRead(self.qcr)
|
||||
(type,dgi) = self.msgHandler.readHeader(datagram)
|
||||
if type != CLUSTER_SWAP_READY:
|
||||
self.notify.warning( ('was expecting SWAP_READY, got %d' % type) )
|
||||
while 1:
|
||||
(datagram, dgi,type) = self.msgHandler.blockingRead(self.qcr)
|
||||
if type == CLUSTER_SWAP_READY:
|
||||
break
|
||||
else:
|
||||
self.notify.warning('was expecting SWAP_READY, got %d' % type)
|
||||
|
||||
# the following should only be called by a synchronized cluster manger
|
||||
def sendSwapNow(self):
|
||||
@ -97,6 +95,13 @@ class DisplayConnection:
|
||||
datagram = self.msgHandler.makeCommandStringDatagram(commandString)
|
||||
self.cw.send(datagram, self.tcpConn)
|
||||
|
||||
def sendExit(self):
|
||||
ClusterManager.notify.debug(
|
||||
"display connect send exit, packet %d" %
|
||||
self.msgHandler.packetNumber)
|
||||
datagram = self.msgHandler.makeExitDatagram()
|
||||
self.cw.send(datagram, self.tcpConn)
|
||||
|
||||
class ClusterManager(DirectObject.DirectObject):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("ClusterClient")
|
||||
MGR_NUM = 1000000
|
||||
@ -127,9 +132,7 @@ class ClusterManager(DirectObject.DirectObject):
|
||||
server.sendMoveCam(xyz,hpr)
|
||||
|
||||
def startMoveCamTask(self):
|
||||
task = Task.Task(self.moveCameraTask,49)
|
||||
taskMgr.add(task, "moveCamTask")
|
||||
return None
|
||||
taskMgr.add(self.moveCameraTask, "moveCamTask", 49)
|
||||
|
||||
def moveCameraTask(self,task):
|
||||
self.moveCamera(
|
||||
@ -142,7 +145,15 @@ class ClusterManager(DirectObject.DirectObject):
|
||||
for server in self.serverList:
|
||||
server.sendCommandString(commandString)
|
||||
# Execute locally
|
||||
exec( commandString, globals() )
|
||||
exec( commandString, globals())
|
||||
|
||||
def exit(self):
|
||||
# Execute remotely
|
||||
for server in self.serverList:
|
||||
server.sendExit()
|
||||
# Execute locally
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
class ClusterManagerSync(ClusterManager):
|
||||
|
||||
@ -154,8 +165,7 @@ class ClusterManagerSync(ClusterManager):
|
||||
self.startSwapCoordinatorTask()
|
||||
|
||||
def startSwapCoordinatorTask(self):
|
||||
task = Task.Task(self.swapCoordinator,51)
|
||||
taskMgr.add(task, "clientSwapCoordinator")
|
||||
taskMgr.add(self.swapCoordinator, "clientSwapCoordinator", 51)
|
||||
return None
|
||||
|
||||
def swapCoordinator(self,task):
|
||||
|
@ -23,7 +23,7 @@ ClientConfigs = {
|
||||
{'pos' : Vec3(0),
|
||||
'hpr' : Vec3(60,0,0)}
|
||||
],
|
||||
'cavetest' : [{'pos' : Vec3(-0.105, -0.020, 5.000),
|
||||
'cavetest-old' : [{'pos' : Vec3(-0.105, -0.020, 5.000),
|
||||
'hpr' : Vec3(51.213, 0.000, 0.000),
|
||||
'focal length' : 0.809,
|
||||
'film size' : (1.000, 0.831),
|
||||
@ -48,7 +48,7 @@ ClientConfigs = {
|
||||
'film offset' : (0.000, 0.173),
|
||||
},
|
||||
],
|
||||
'cavetest-all' : [{'pos' : Vec3(-0.105, -0.020, 5.000),
|
||||
'cavetest' : [{'pos' : Vec3(-0.105, -0.020, 5.000),
|
||||
'hpr' : Vec3(51.213, 0.000, 0.000),
|
||||
'focal length' : 0.809,
|
||||
'film size' : (1.000, 0.831),
|
||||
@ -100,7 +100,7 @@ def createClusterManager():
|
||||
displayConfigs = []
|
||||
configList = ClientConfigs[clusterConfig]
|
||||
numConfigs = len(configList)
|
||||
for i in range(numConfigs):
|
||||
for i in range(1,numConfigs):
|
||||
configData = configList[i]
|
||||
serverConfigName = 'display%d' % i
|
||||
serverString = base.config.GetString(serverConfigName, '')
|
||||
|
@ -7,70 +7,77 @@
|
||||
# recieved are handled outside of here, after the header (message type
|
||||
# and number) are read here.
|
||||
|
||||
from PandaModules import *
|
||||
import Datagram
|
||||
import time
|
||||
|
||||
#these are the types of messages that are currently supported.
|
||||
CLUSTER_NOTHING = -1
|
||||
CLUSTER_NONE = 0
|
||||
CLUSTER_CAM_OFFSET = 1
|
||||
CLUSTER_CAM_FRUSTUM = 2
|
||||
CLUSTER_POS_UPDATE = 3
|
||||
CLUSTER_CAM_MOVEMENT = 3
|
||||
CLUSTER_SWAP_READY = 4
|
||||
CLUSTER_SWAP_NOW = 5
|
||||
CLUSTER_COMMAND_STRING = 6
|
||||
CLUSTER_EXIT = 100
|
||||
|
||||
#Port number for cluster rendering
|
||||
CLUSTER_PORT = 1970
|
||||
|
||||
from ShowBaseGlobal import *
|
||||
from PandaModules import *
|
||||
from TaskManagerGlobal import *
|
||||
import Task
|
||||
import DirectNotifyGlobal
|
||||
import Datagram
|
||||
import time
|
||||
|
||||
class MsgHandler:
|
||||
"""MsgHandler: wrapper for PC clusters/multi-piping networking"""
|
||||
def __init__(self,packetStart, notify):
|
||||
#packetStart can be used to distinguish which MsgHandler sends a
|
||||
#given packet.
|
||||
# packetStart can be used to distinguish which MsgHandler sends a
|
||||
# given packet.
|
||||
self.packetNumber = packetStart
|
||||
self.notify = notify
|
||||
|
||||
def nonBlockingRead(self,qcr):
|
||||
availGetVal = qcr.dataAvailable()
|
||||
if availGetVal:
|
||||
"""
|
||||
Return a datagram iterator and type if data is available on the
|
||||
queued connection reader
|
||||
"""
|
||||
if qcr.dataAvailable():
|
||||
datagram = NetDatagram()
|
||||
readRetVal = qcr.getData(datagram)
|
||||
if readRetVal:
|
||||
dgi = DatagramIterator(datagram)
|
||||
number = dgi.getUint32()
|
||||
type = dgi.getUint8()
|
||||
self.notify.debug( ("Packet %d type %d recieved" % (number,type)) )
|
||||
if qcr.getData(datagram):
|
||||
(dgi, type) = self.readHeader(datagram)
|
||||
else:
|
||||
dgi = None
|
||||
type = CLUSTER_NONE
|
||||
self.notify.warning("getData returned false")
|
||||
else:
|
||||
type = CLUSTER_NOTHING
|
||||
dgi = None
|
||||
return (type,dgi)
|
||||
|
||||
def readHeader(self,datagram):
|
||||
dgi = DatagramIterator(datagram)
|
||||
number = dgi.getUint32()
|
||||
type = dgi.getUint8()
|
||||
self.notify.debug( ("Packet %d type %d recieved" % (number,type)) )
|
||||
return (type,dgi)
|
||||
type = CLUSTER_NONE
|
||||
# Note, return datagram to keep a handle on the data
|
||||
return (datagram, dgi,type)
|
||||
|
||||
def blockingRead(self,qcr):
|
||||
"""
|
||||
Block until data is available on the queued connection reader.
|
||||
Returns a datagram iterator and type
|
||||
"""
|
||||
while not qcr.dataAvailable():
|
||||
# The following may not be necessary.
|
||||
# I just wanted some
|
||||
# time given to the operating system while
|
||||
# busy waiting.
|
||||
time.sleep(0.002)
|
||||
# Data is available, create a datagram iterator
|
||||
datagram = NetDatagram()
|
||||
readRetVal = qcr.getData(datagram)
|
||||
if not readRetVal:
|
||||
if qcr.getData(datagram):
|
||||
(dgi, type) = self.readHeader(datagram)
|
||||
else:
|
||||
(dgi, type) = (None, CLUSTER_NONE)
|
||||
self.notify.warning("getData returned false")
|
||||
return datagram
|
||||
# Note, return datagram to keep a handle on the data
|
||||
return (datagram, dgi, type)
|
||||
|
||||
def readHeader(self,datagram):
|
||||
dgi = DatagramIterator(datagram)
|
||||
number = dgi.getUint32()
|
||||
type = dgi.getUint8()
|
||||
self.notify.debug("Packet %d type %d recieved" % (number,type))
|
||||
return (dgi,type)
|
||||
|
||||
def makeCamOffsetDatagram(self,xyz,hpr):
|
||||
datagram = Datagram.Datagram()
|
||||
@ -85,14 +92,6 @@ class MsgHandler:
|
||||
datagram.addFloat32(hpr[2])
|
||||
return datagram
|
||||
|
||||
def makeCommandStringDatagram(self, commandString):
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
self.packetNumber = self.packetNumber + 1
|
||||
datagram.addUint8(CLUSTER_COMMAND_STRING)
|
||||
datagram.addString(commandString)
|
||||
return datagram
|
||||
|
||||
def makeCamFrustumDatagram(self,focalLength, filmSize, filmOffset):
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
@ -109,7 +108,7 @@ class MsgHandler:
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
self.packetNumber = self.packetNumber + 1
|
||||
datagram.addUint8(CLUSTER_POS_UPDATE)
|
||||
datagram.addUint8(CLUSTER_CAM_MOVEMENT)
|
||||
datagram.addFloat32(xyz[0])
|
||||
datagram.addFloat32(xyz[1])
|
||||
datagram.addFloat32(xyz[2])
|
||||
@ -118,6 +117,14 @@ class MsgHandler:
|
||||
datagram.addFloat32(hpr[2])
|
||||
return datagram
|
||||
|
||||
def makeCommandStringDatagram(self, commandString):
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
self.packetNumber = self.packetNumber + 1
|
||||
datagram.addUint8(CLUSTER_COMMAND_STRING)
|
||||
datagram.addString(commandString)
|
||||
return datagram
|
||||
|
||||
def makeSwapNowDatagram(self):
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
@ -132,6 +139,13 @@ class MsgHandler:
|
||||
datagram.addUint8(CLUSTER_SWAP_READY)
|
||||
return datagram
|
||||
|
||||
def makeExitDatagram(self):
|
||||
datagram = Datagram.Datagram()
|
||||
datagram.addUint32(self.packetNumber)
|
||||
self.packetNumber = self.packetNumber + 1
|
||||
datagram.addUint8(CLUSTER_EXIT)
|
||||
return datagram
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
"""ServerRepository module: contains the ServerRepository class"""
|
||||
|
||||
from ShowBaseGlobal import *
|
||||
from ClusterMsgs import *
|
||||
import DirectObject
|
||||
import Datagram
|
||||
#import DatagramIterator
|
||||
#import NetDatagram
|
||||
import __builtin__
|
||||
import time
|
||||
from PandaModules import *
|
||||
from TaskManagerGlobal import *
|
||||
from ClusterMsgs import *
|
||||
from MsgTypes import *
|
||||
import Task
|
||||
import DirectNotifyGlobal
|
||||
import DirectObject
|
||||
import Task
|
||||
|
||||
# Cam offset handling is a little sloppy. The problem is that there is a
|
||||
# single arc used for both movement of the camera, and the offset of the
|
||||
@ -76,32 +69,32 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
# Run this task just after the listener poll task and dataloop
|
||||
taskMgr.add(self.readerPollTask, "serverReaderPollTask", -39)
|
||||
|
||||
def readerPollTask(self):
|
||||
while self.qcr.dataAvailable():
|
||||
datagram = NetDatagram()
|
||||
readRetVal = self.qcr.getData(datagram)
|
||||
if readRetVal:
|
||||
self.handleDatagram(datagram)
|
||||
def readerPollTask(self, state):
|
||||
# Process all available datagrams
|
||||
while 1:
|
||||
(datagram, dgi,type) = self.msgHandler.nonBlockingRead(self.qcr)
|
||||
if type is CLUSTER_NONE:
|
||||
break
|
||||
else:
|
||||
self.notify.warning("getData returned false")
|
||||
handleDatagram(dgi, type)
|
||||
return Task.cont
|
||||
|
||||
def handleDatagram(self, datagram):
|
||||
(type, dgi) = self.msgHandler.nonBlockingRead(self.qcr)
|
||||
if type==CLUSTER_CAM_OFFSET:
|
||||
def handleDatagram(self, dgi, type):
|
||||
if type == CLUSTER_NONE:
|
||||
pass
|
||||
elif type == CLUSTER_EXIT:
|
||||
import sys
|
||||
sys.exit()
|
||||
elif type == CLUSTER_CAM_OFFSET:
|
||||
self.handleCamOffset(dgi)
|
||||
elif type==CLUSTER_CAM_FRUSTUM:
|
||||
elif type == CLUSTER_CAM_FRUSTUM:
|
||||
self.handleCamFrustum(dgi)
|
||||
elif type==CLUSTER_POS_UPDATE:
|
||||
elif type == CLUSTER_CAM_MOVEMENT:
|
||||
self.handleCamMovement(dgi)
|
||||
elif type==CLUSTER_SWAP_READY:
|
||||
pass
|
||||
elif type==CLUSTER_SWAP_NOW:
|
||||
pass
|
||||
elif type==CLUSTER_COMMAND_STRING:
|
||||
elif type == CLUSTER_COMMAND_STRING:
|
||||
self.handleCommandString(dgi)
|
||||
else:
|
||||
self.notify.warning("recieved unknown packet")
|
||||
self.notify.warning("Recieved unknown packet type:" % type)
|
||||
return type
|
||||
|
||||
def handleCamOffset(self,dgi):
|
||||
@ -147,7 +140,7 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
|
||||
def handleCommandString(self, dgi):
|
||||
command = dgi.getString()
|
||||
exec( command, globals() )
|
||||
exec( command, globals())
|
||||
|
||||
class ClusterServerSync(ClusterServer):
|
||||
|
||||
@ -163,11 +156,10 @@ class ClusterServerSync(ClusterServer):
|
||||
pass
|
||||
elif self.qcr.isConnectionOk(self.lastConnection):
|
||||
# Process datagrams till you get a postion update
|
||||
type = CLUSTER_NOTHING
|
||||
while type != CLUSTER_POS_UPDATE:
|
||||
datagram = self.msgHandler.blockingRead(self.qcr)
|
||||
(type,dgi) = self.msgHandler.readHeader(datagram)
|
||||
if type == CLUSTER_POS_UPDATE:
|
||||
type = CLUSTER_NONE
|
||||
while type != CLUSTER_CAM_MOVEMENT:
|
||||
(datagram,dgi,type) = self.msgHandler.blockingRead(self.qcr)
|
||||
if type == CLUSTER_CAM_MOVEMENT:
|
||||
# Move camera
|
||||
self.handleCamMovement(dgi)
|
||||
# Set flag for swap coordinator
|
||||
@ -194,13 +186,14 @@ class ClusterServerSync(ClusterServer):
|
||||
if self.posRecieved:
|
||||
self.posRecieved = 0
|
||||
self.sendSwapReady()
|
||||
datagram = self.msgHandler.blockingRead(self.qcr)
|
||||
(type,dgi) = self.msgHandler.readHeader(datagram)
|
||||
while 1:
|
||||
(datagram,dgi,type) = self.msgHandler.blockingRead(self.qcr)
|
||||
if type == CLUSTER_SWAP_NOW:
|
||||
self.notify.debug('swapping')
|
||||
base.win.swap()
|
||||
break
|
||||
else:
|
||||
self.notify.warning("did not get expected swap now")
|
||||
self.handleDatagram(dgi,type)
|
||||
return Task.cont
|
||||
|
||||
|
||||
|
@ -260,11 +260,23 @@ class DirectCameraControl(PandaObject):
|
||||
angle = getCrankAngle(state.coaCenter)
|
||||
deltaAngle = angle - state.lastAngle
|
||||
state.lastAngle = angle
|
||||
if deltaAngle != 0.0:
|
||||
print deltaAngle
|
||||
print 'cam Manip before'
|
||||
print self.camManipRef.getMat()
|
||||
if base.config.GetBool('temp-hpr-fix',0):
|
||||
self.camManipRef.setHpr(self.camManipRef, 0, 0, deltaAngle)
|
||||
else:
|
||||
self.camManipRef.setHpr(self.camManipRef, 0, 0, -deltaAngle)
|
||||
print 'cam Manip after'
|
||||
print self.camManipRef.getMat()
|
||||
print 'direct camera before'
|
||||
print direct.camera.getMat()
|
||||
direct.camera.setMat(self.camManipRef, wrtMat)
|
||||
print 'direct camera after'
|
||||
print direct.camera.getMat()
|
||||
print
|
||||
print
|
||||
return Task.cont
|
||||
|
||||
def lockCOA(self):
|
||||
@ -352,6 +364,8 @@ class DirectCameraControl(PandaObject):
|
||||
# ref = base.cam
|
||||
ref = direct.drList.getCurrentDr().cam
|
||||
self.coaMarker.setPos(ref, self.coa)
|
||||
pos = self.coaMarker.getPos()
|
||||
self.coaMarker.setPosHprScale(pos, Vec3(0), Vec3(1))
|
||||
# Resize it
|
||||
self.updateCoaMarkerSize(coaDist)
|
||||
# Record marker pos in render space
|
||||
|
@ -98,7 +98,7 @@ class DirectManipulationControl(PandaObject):
|
||||
self.hitPt.assign(hitPt)
|
||||
self.hitPtDist = hitPtDist
|
||||
# Find the node path from the node found above
|
||||
nodePath = render.findPathDownTo(node)
|
||||
nodePath = render.findAllPathsTo(node)[0]
|
||||
# Select it
|
||||
direct.select(nodePath, direct.fShift)
|
||||
else:
|
||||
@ -223,7 +223,7 @@ class DirectManipulationControl(PandaObject):
|
||||
self.objectHandles.transferObjectHandlesScale()
|
||||
self.fScaling = 0
|
||||
# Alt key switches to a scaling mode
|
||||
if direct.fAlt:
|
||||
if direct.fControl:
|
||||
self.fScaling = 1
|
||||
self.scale3D(state)
|
||||
# Otherwise, manip mode depends on where you started
|
||||
|
@ -22,7 +22,7 @@ class DirectNodePath(NodePath):
|
||||
# and its center of action (COA)
|
||||
self.mCoa2Dnp = Mat4()
|
||||
self.mCoa2Dnp.assign(Mat4.identMat())
|
||||
# self.mCoa2Dnp.setRow(3, Vec4(center[0], center[1], center[2], 1))
|
||||
self.mCoa2Dnp.setRow(3, Vec4(center[0], center[1], center[2], 1))
|
||||
# Transform from nodePath to widget
|
||||
self.mDnp2Widget = Mat4()
|
||||
self.mDnp2Widget.assign(Mat4.identMat())
|
||||
@ -127,18 +127,7 @@ class SelectedNodePaths(PandaObject):
|
||||
"""
|
||||
dnp = self.selectedDict.get(id, None)
|
||||
if dnp:
|
||||
# Found item in selected Dictionary, is it still valid?
|
||||
if dnp.verifyConnectivity():
|
||||
# Yes
|
||||
return dnp
|
||||
else:
|
||||
# Not valid anymore, try to repair
|
||||
if dnp.repairConnectivity(render):
|
||||
# Fixed, return node path
|
||||
return dnp
|
||||
else:
|
||||
del(self.selectedDict[id])
|
||||
return None
|
||||
else:
|
||||
# Not in selected dictionary
|
||||
return None
|
||||
@ -152,18 +141,8 @@ class SelectedNodePaths(PandaObject):
|
||||
"""
|
||||
dnp = self.deselectedDict.get(id, None)
|
||||
if dnp:
|
||||
# Found item in deselected Dictionary, is it still valid?
|
||||
if dnp.verifyConnectivity():
|
||||
# Yes
|
||||
return dnp
|
||||
else:
|
||||
# Not valid anymore, try to repair
|
||||
if dnp.repairConnectivity(render):
|
||||
# Fixed, return node path
|
||||
return dnp
|
||||
else:
|
||||
del(self.deselectedDict[id])
|
||||
return None
|
||||
else:
|
||||
# Not in deselected dictionary
|
||||
return None
|
||||
@ -344,9 +323,10 @@ class DirectBoundingBox:
|
||||
|
||||
def getBounds(self):
|
||||
# Get a node path's bounds
|
||||
nodeBounds = self.nodePath.node().getBound()
|
||||
nodeBounds = BoundingSphere()
|
||||
nodeBounds.extendBy(self.nodePath.node().getInternalBound())
|
||||
for child in self.nodePath.getChildrenAsList():
|
||||
nodeBounds.extendBy(child.arc().getBound())
|
||||
nodeBounds.extendBy(child.getBounds())
|
||||
return nodeBounds.makeCopy()
|
||||
|
||||
def show(self):
|
||||
@ -428,11 +408,11 @@ class SelectionRay:
|
||||
for i in range(0,self.numEntries):
|
||||
entry = self.cq.getEntry(i)
|
||||
node = entry.getIntoNode()
|
||||
nodePath = render.findPathDownTo(node)
|
||||
nodePath = render.findAllPathsTo(node)[0]
|
||||
# Don't pick hidden nodes
|
||||
if node.isHidden():
|
||||
pass
|
||||
elif fIgnoreCamera and (direct.camera in nodePath.getAncestry()):
|
||||
#if node.isHidden():
|
||||
#pass
|
||||
if fIgnoreCamera and (direct.camera in nodePath.getAncestry()):
|
||||
# This avoids things parented to a camera. Good idea?
|
||||
pass
|
||||
# Can pick unpickable, use the first visible node
|
||||
@ -520,10 +500,11 @@ class SelectionRay:
|
||||
entry = self.cq.getEntry(i)
|
||||
node = entry.getIntoNode()
|
||||
# Don't pick hidden nodes
|
||||
if node.isHidden():
|
||||
pass
|
||||
# MRM: Doesn't work in new panda for GeomNodes
|
||||
#if node.isHidden():
|
||||
#pass
|
||||
# Can pick unpickable, use the first visible node
|
||||
elif fIntersectUnpickable:
|
||||
if fIntersectUnpickable:
|
||||
self.cqIndex = i
|
||||
break
|
||||
# Is it a named node?, If so, see if it has a name
|
||||
|
@ -96,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')
|
||||
@ -383,8 +378,8 @@ class ShowBase:
|
||||
|
||||
|
||||
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.
|
||||
"""
|
||||
@ -393,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()
|
||||
|
||||
@ -409,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())
|
||||
@ -576,12 +570,13 @@ class ShowBase:
|
||||
self.backfaceCullingOn()
|
||||
|
||||
def backfaceCullingOn(self):
|
||||
self.render.setTwoSided(self.wireframeEnabled)
|
||||
if not self.backfaceCullingEnabled:
|
||||
self.render.setTwoSided(0)
|
||||
self.backfaceCullingEnabled = 1
|
||||
|
||||
def backfaceCullingOff(self):
|
||||
if not self.wireframeEnabled:
|
||||
self.render.setTwoSided(0)
|
||||
if self.backfaceCullingEnabled:
|
||||
self.render.setTwoSided(1)
|
||||
self.backfaceCullingEnabled = 0
|
||||
|
||||
def toggleTexture(self):
|
||||
|
@ -5,6 +5,7 @@ from MessengerGlobal import *
|
||||
import time
|
||||
import fnmatch
|
||||
import string
|
||||
import signal
|
||||
|
||||
# MRM: Need to make internal task variables like time, name, index
|
||||
# more unique (less likely to have name clashes)
|
||||
@ -230,6 +231,8 @@ class TaskManager:
|
||||
TaskManager.notify = directNotify.newCategory("TaskManager")
|
||||
self.taskTimerVerbose = 0
|
||||
self.extendedExceptions = 0
|
||||
self.fKeyboardInterrupt = 0
|
||||
self.interruptCount = 0
|
||||
self.pStatsTasks = 0
|
||||
self.resumeFunc = None
|
||||
self.fVerbose = 0
|
||||
@ -241,6 +244,14 @@ class TaskManager:
|
||||
self.fVerbose = value
|
||||
messenger.send('TaskManager-setVerbose', sentArgs = [value])
|
||||
|
||||
def keyboardInterruptHandler(self, signalNumber, stackFrame):
|
||||
self.fKeyboardInterrupt = 1
|
||||
self.interruptCount += 1
|
||||
if self.interruptCount == 2:
|
||||
# The user must really want to interrupt this process
|
||||
# Next time around use the default interrupt handler
|
||||
signal.signal(signal.SIGINT, signal.default_int_handler)
|
||||
|
||||
def add(self, funcOrTask, name, priority = 0):
|
||||
"""
|
||||
Add a new task to the taskMgr.
|
||||
@ -370,6 +381,12 @@ class TaskManager:
|
||||
if TaskManager.notify.getDebug():
|
||||
TaskManager.notify.debug('step')
|
||||
self.currentTime, self.currentFrame = self.__getTimeFrame()
|
||||
# Replace keyboard interrupt handler during task list processing
|
||||
# so we catch the keyboard interrupt but don't handle it until
|
||||
# after task list processing is complete.
|
||||
self.fKeyboardInterrupt = 0
|
||||
self.interruptCount = 0
|
||||
signal.signal(signal.SIGINT, self.keyboardInterruptHandler)
|
||||
for task in self.taskList:
|
||||
task.setCurrentTimeFrame(self.currentTime, self.currentFrame)
|
||||
|
||||
@ -410,6 +427,10 @@ class TaskManager:
|
||||
self.__removeTask(task)
|
||||
else:
|
||||
raise StandardError, "Task named %s did not return cont, exit, or done" % task.name
|
||||
# Restore default interrupt handler
|
||||
signal.signal(signal.SIGINT, signal.default_int_handler)
|
||||
if self.fKeyboardInterrupt:
|
||||
raise KeyboardInterrupt
|
||||
return len(self.taskList)
|
||||
|
||||
def run(self):
|
||||
|
@ -695,7 +695,7 @@ class DirectSessionPanel(AppShell):
|
||||
dictName = name
|
||||
else:
|
||||
# Generate a unique name for the dict
|
||||
dictName = name + '-' + `nodePath.id().this`
|
||||
dictName = name + '-' + `nodePath.id()`
|
||||
if not dict.has_key(dictName):
|
||||
# Update combo box to include new item
|
||||
names.append(dictName)
|
||||
|
@ -292,8 +292,7 @@ class MopathRecorder(AppShell, PandaObject):
|
||||
resolution = 0.01, command = self.playbackGoTo, side = TOP)
|
||||
widget.component('hull')['relief'] = RIDGE
|
||||
# Kill playback task if drag slider
|
||||
widget.component('scale').bind(
|
||||
'<ButtonPress-1>', lambda e = None, s = self: s.stopPlayback())
|
||||
widget['preCallback'] = self.stopPlayback
|
||||
# Jam duration entry into entry scale
|
||||
self.createLabeledEntry(widget.labelFrame, 'Resample', 'Path Duration',
|
||||
'Set total curve duration',
|
||||
@ -371,7 +370,7 @@ class MopathRecorder(AppShell, PandaObject):
|
||||
'Number of samples in resampled curve',
|
||||
resolution = 1, min = 2, max = 1000, command = self.setNumSamples)
|
||||
widget.component('hull')['relief'] = RIDGE
|
||||
widget['preCallback'] = widget['postCallback'] = self.sampleCurve
|
||||
widget['postCallback'] = self.sampleCurve
|
||||
|
||||
frame = Frame(resampleFrame)
|
||||
self.createButton(
|
||||
@ -785,7 +784,9 @@ class MopathRecorder(AppShell, PandaObject):
|
||||
def extractPointSetFromCurveCollection(self):
|
||||
# Use curve to compute new point set
|
||||
# Record maxT
|
||||
print 'before', self.maxT
|
||||
self.maxT = self.curveCollection.getMaxT()
|
||||
print 'after', self.maxT
|
||||
# Determine num samples
|
||||
# Limit point set to 1000 points and samples per second to 30
|
||||
samplesPerSegment = min(30.0, 1000.0/self.curveCollection.getMaxT())
|
||||
@ -1232,7 +1233,7 @@ class MopathRecorder(AppShell, PandaObject):
|
||||
dictName = name
|
||||
else:
|
||||
# Generate a unique name for the dict
|
||||
dictName = name + '-' + `nodePath.id().this`
|
||||
dictName = name + '-' + `nodePath.id()`
|
||||
if not dict.has_key(dictName):
|
||||
# Update combo box to include new item
|
||||
names.append(dictName)
|
||||
@ -1248,7 +1249,6 @@ class MopathRecorder(AppShell, PandaObject):
|
||||
def playbackGoTo(self, time):
|
||||
if self.curveCollection == None:
|
||||
return
|
||||
print time
|
||||
self.playbackTime = CLAMP(time, 0.0, self.maxT)
|
||||
if self.curveCollection != None:
|
||||
pos = Point3(0)
|
||||
|
@ -493,7 +493,7 @@ class Placer(AppShell):
|
||||
dictName = name
|
||||
else:
|
||||
# Generate a unique name for the dict
|
||||
dictName = name + '-' + `nodePath.id().this`
|
||||
dictName = name + '-' + `nodePath.id()`
|
||||
if not dict.has_key(dictName):
|
||||
# Update combo box to include new item
|
||||
names.append(dictName)
|
||||
|
@ -374,6 +374,8 @@ class SliderWidget(Pmw.MegaWidget):
|
||||
if fInside:
|
||||
self._fPressInside = 1
|
||||
self._fUpdate = 1
|
||||
if self['preCallback']:
|
||||
apply(self['preCallback'], self['callbackData'])
|
||||
self._updateValue(event)
|
||||
else:
|
||||
self._fPressInside = 0
|
||||
@ -385,11 +387,16 @@ class SliderWidget(Pmw.MegaWidget):
|
||||
event.y_root - self._widget.winfo_rooty())
|
||||
if canvasY > 0:
|
||||
self._fUpdate = 1
|
||||
if self['preCallback']:
|
||||
apply(self['preCallback'], self['callbackData'])
|
||||
self._unpostOnNextRelease()
|
||||
elif self._fUpdate:
|
||||
self._updateValue(event)
|
||||
|
||||
def _widgetBtnRelease(self, event):
|
||||
# Do post callback if any
|
||||
if self._fUpdate and self['postCallback']:
|
||||
apply(self['postCallback'], self['callbackData'])
|
||||
if (self._fUnpost or
|
||||
(not (self._firstPress or self._fPressInside))):
|
||||
self._unpostSlider()
|
||||
|
Loading…
x
Reference in New Issue
Block a user