mirror of
https://github.com/panda3d/panda3d.git
synced 2026-04-27 01:35:55 -05:00
direct: More code style changes
This commit is contained in:
@@ -493,7 +493,8 @@ disable=raw-checker-failed,
|
||||
using-constant-test,
|
||||
wrong-import-order,
|
||||
wrong-import-position,
|
||||
not-callable
|
||||
not-callable,
|
||||
wildcard-import
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
@@ -615,6 +616,7 @@ contextmanager-decorators=contextlib.contextmanager
|
||||
# expressions are accepted.
|
||||
generated-members=base.cr,
|
||||
base.le,
|
||||
base.localAvatar,
|
||||
Pmw.AboutDialog,
|
||||
Pmw.Balloon,
|
||||
Pmw.ButtonBox,
|
||||
@@ -629,8 +631,10 @@ generated-members=base.cr,
|
||||
Pmw.MenuBar,
|
||||
Pmw.MessageBar,
|
||||
Pmw.NoteBook,
|
||||
Pmw.OK,
|
||||
Pmw.OptionMenu,
|
||||
Pmw.OptionMenu,
|
||||
Pmw.PARTIAL,
|
||||
Pmw.PanedWidget,
|
||||
Pmw.ScrolledCanvas,
|
||||
Pmw.ScrolledFrame,
|
||||
@@ -640,8 +644,10 @@ generated-members=base.cr,
|
||||
Pmw.aboutcopyright,
|
||||
Pmw.aboutversion,
|
||||
Pmw.forwardmethods,
|
||||
Pmw.integervalidator,
|
||||
Pmw.popgrab,
|
||||
Pmw.pushgrab,
|
||||
Pmw.realvalidator,
|
||||
Pmw.setgeometryanddeiconify
|
||||
|
||||
# Tells whether to warn about missing members when the owner of the attribute
|
||||
@@ -699,7 +705,8 @@ additional-builtins=base,
|
||||
cluster,
|
||||
launcher,
|
||||
taskMgr,
|
||||
localAvatar
|
||||
localAvatar,
|
||||
game
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
@@ -113,7 +113,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
self.notify.debug('post startMoveCam')
|
||||
self.startMoveSelectedTask()
|
||||
|
||||
|
||||
def startReaderPollTask(self):
|
||||
""" Task to handle datagrams from server """
|
||||
# Run this task just after the listener poll task
|
||||
@@ -130,7 +129,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
|
||||
return Task.cont
|
||||
|
||||
|
||||
def startControlObjectTask(self):
|
||||
self.notify.debug("moving control objects")
|
||||
taskMgr.add(self.controlObjectTask,"controlObjectTask",50)
|
||||
@@ -152,7 +150,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
self.notify.debug('adding move cam')
|
||||
taskMgr.add(self.moveCameraTask, "moveCamTask", 49)
|
||||
|
||||
|
||||
def controlObjectTask(self, task):
|
||||
for pair in self.sortedControlMappings:
|
||||
object = pair[1]
|
||||
@@ -171,8 +168,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
for server in serverList:
|
||||
self.serverList[server].sendNamedMovementDone()
|
||||
|
||||
|
||||
|
||||
def redoSortedPriorities(self):
|
||||
self.sortedControlMappings = []
|
||||
for key in self.controlMappings:
|
||||
@@ -194,7 +189,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
for server in serverList:
|
||||
self.serverList[server].sendMoveNamedObject(xyz,hpr,scale,color,hidden,object)
|
||||
|
||||
|
||||
def moveCameraTask(self, task):
|
||||
self.moveCamera(
|
||||
base.camera.getPos(render),
|
||||
@@ -221,7 +215,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
server.sendMoveSelected(xyz, hpr, scale)
|
||||
return Task.cont
|
||||
|
||||
|
||||
def addNamedObjectMapping(self, object, name, hasColor = True):
|
||||
if name not in self.objectMappings:
|
||||
self.objectMappings[name] = object
|
||||
@@ -233,7 +226,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
if name in self.objectMappings:
|
||||
self.objectMappings.pop(name)
|
||||
|
||||
|
||||
def addControlMapping(self, objectName, controlledName, serverList = None,
|
||||
offset = None, priority = 0):
|
||||
if objectName not in self.controlMappings:
|
||||
@@ -278,7 +270,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
self.controlPriorities.pop(name)
|
||||
self.redoSortedPriorities()
|
||||
|
||||
|
||||
def getNodePathFindCmd(self, nodePath):
|
||||
pathString = repr(nodePath)
|
||||
index = pathString.find('/')
|
||||
@@ -298,7 +289,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
else:
|
||||
return pathString
|
||||
|
||||
|
||||
def addObjectTag(self,object,selectFunction,deselectFunction,selectArgs,deselectArgs):
|
||||
newTag = {}
|
||||
newTag["selectFunction"] = selectFunction
|
||||
@@ -307,12 +297,10 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
newTag["deselectArgs"] = deselectArgs
|
||||
self.taggedObjects[object] = newTag
|
||||
|
||||
|
||||
def removeObjectTag(self,object):
|
||||
|
||||
self.taggedObjects.pop(object)
|
||||
|
||||
|
||||
def selectNodePath(self, nodePath):
|
||||
name = self.getNodePathName(nodePath)
|
||||
if name in self.taggedObjects:
|
||||
@@ -325,7 +313,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
else:
|
||||
self(self.getNodePathFindCmd(nodePath) + '.select()', 0)
|
||||
|
||||
|
||||
def deselectNodePath(self, nodePath):
|
||||
name = self.getNodePathName(nodePath)
|
||||
if name in self.taggedObjects:
|
||||
@@ -363,7 +350,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
# Execute locally
|
||||
exec(commandString, __builtins__)
|
||||
|
||||
|
||||
def handleDatagram(self,dgi,type,server):
|
||||
if type == CLUSTER_NONE:
|
||||
pass
|
||||
@@ -388,7 +374,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
# clear the queue
|
||||
self.serverQueues[server] = []
|
||||
|
||||
|
||||
def handleNamedMovement(self, data):
|
||||
""" Update cameraJig position to reflect latest position """
|
||||
|
||||
@@ -408,7 +393,6 @@ class ClusterClient(DirectObject.DirectObject):
|
||||
else:
|
||||
self.notify.debug("recieved unknown named object command: "+name)
|
||||
|
||||
|
||||
def exit(self):
|
||||
# Execute remotely
|
||||
for server in self.serverList:
|
||||
@@ -475,8 +459,6 @@ class DisplayConnection:
|
||||
self.qcr.addConnection(self.tcpConn)
|
||||
self.cw=ConnectionWriter(qcm, 0)
|
||||
|
||||
|
||||
|
||||
def poll(self):
|
||||
""" Non blocking task to read all available datagrams """
|
||||
dataGrams = []
|
||||
@@ -491,9 +473,6 @@ class DisplayConnection:
|
||||
|
||||
return dataGrams
|
||||
|
||||
|
||||
|
||||
|
||||
def sendCamOffset(self, xyz, hpr):
|
||||
ClusterClient.notify.debug("send cam offset...")
|
||||
ClusterClient.notify.debug(("packet %d xyz, hpr=%f %f %f %f %f %f" %
|
||||
@@ -509,12 +488,11 @@ class DisplayConnection:
|
||||
(" fl, fs, fo=%0.3f, (%0.3f, %0.3f), (%0.3f, %0.3f)" %
|
||||
(focalLength, filmSize[0], filmSize[1],
|
||||
filmOffset[0], filmOffset[1])))
|
||||
)
|
||||
)
|
||||
datagram = self.msgHandler.makeCamFrustumDatagram(
|
||||
focalLength, filmSize, filmOffset)
|
||||
self.cw.send(datagram, self.tcpConn)
|
||||
|
||||
|
||||
def sendNamedMovementDone(self):
|
||||
|
||||
datagram = self.msgHandler.makeNamedMovementDone()
|
||||
@@ -584,6 +562,7 @@ class DisplayConnection:
|
||||
frameCount, frameTime, dt)
|
||||
self.cw.send(datagram, self.tcpConn)
|
||||
|
||||
|
||||
class ClusterConfigItem:
|
||||
def __init__(self, serverConfigName, serverName,
|
||||
serverDaemonPort, serverMsgPort):
|
||||
@@ -599,9 +578,11 @@ class ClusterConfigItem:
|
||||
self.focalLength = None
|
||||
self.filmSize = None
|
||||
self.filmOffset = None
|
||||
|
||||
def setCamOffset(self, xyz, hpr):
|
||||
self.xyz = xyz
|
||||
self.hpr = hpr
|
||||
|
||||
def setCamFrustum(self, focalLength, filmSize, filmOffset):
|
||||
self.fFrustum = 1
|
||||
self.focalLength = focalLength
|
||||
@@ -689,6 +670,7 @@ def createClusterClient():
|
||||
class DummyClusterClient(DirectObject.DirectObject):
|
||||
""" Dummy class to handle command strings when not in cluster mode """
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("DummyClusterClient")
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ ClientConfigs = {
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(0),
|
||||
'hpr': Vec3(0)}
|
||||
],
|
||||
],
|
||||
'two-server': [{'display name': 'master',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(0),
|
||||
@@ -35,7 +35,7 @@ ClientConfigs = {
|
||||
'pos': Vec3(0),
|
||||
'hpr': Vec3(0)
|
||||
}
|
||||
],
|
||||
],
|
||||
'three-server': [{'display name': 'master',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(0),
|
||||
@@ -48,14 +48,14 @@ ClientConfigs = {
|
||||
'pos': Vec3(0),
|
||||
'hpr': Vec3(0)
|
||||
}
|
||||
],
|
||||
],
|
||||
'mono-cave': [{'display name': 'la',
|
||||
'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),
|
||||
'film offset': (0.000, 0.173),
|
||||
},
|
||||
},
|
||||
{'display name': 'lb',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(-0.105, -0.020, 5.000),
|
||||
@@ -71,7 +71,7 @@ ClientConfigs = {
|
||||
'film size': (1.000, 0.830),
|
||||
'film offset': (-0.000, 0.173),
|
||||
},
|
||||
],
|
||||
],
|
||||
'seamless-cave': [{'display name': 'master',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(-0.105, -0.020, 5.000),
|
||||
@@ -79,7 +79,7 @@ ClientConfigs = {
|
||||
'focal length': 0.815,
|
||||
'film size': (1.000, 0.831),
|
||||
'film offset': (0.000, 0.173),
|
||||
},
|
||||
},
|
||||
{'display name': 'la',
|
||||
'pos': Vec3(-0.105, -0.020, 5.000),
|
||||
'hpr': Vec3(51.213, 0.000, 0.000),
|
||||
@@ -122,12 +122,12 @@ ClientConfigs = {
|
||||
'film size': (1.000, 0.831),
|
||||
'film offset': (-0.000, 0.173),
|
||||
},
|
||||
],
|
||||
],
|
||||
'ursula': [{'display name': 'master',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(0),
|
||||
'hpr': Vec3(0),
|
||||
},
|
||||
},
|
||||
{'display name': 'l',
|
||||
'pos': Vec3(-.105, 0, 0),
|
||||
'hpr': Vec3(0, 0, 0),
|
||||
@@ -144,11 +144,11 @@ ClientConfigs = {
|
||||
#'film offset': (-0.105, -2),
|
||||
'film offset': (-0.105, -1),
|
||||
}
|
||||
],
|
||||
],
|
||||
'composite': [{'display name': 'master',
|
||||
'display mode': 'client',
|
||||
'pos': Vec3(0),
|
||||
},
|
||||
},
|
||||
{'display name': 'left',
|
||||
'pos': Vec3(-0.105, -0.020, 5.000),
|
||||
'hpr': Vec3(-0.370, 0.000, 0.000),
|
||||
@@ -163,5 +163,5 @@ ClientConfigs = {
|
||||
'film size': (1.000, 0.831),
|
||||
'film offset': (0.000, 0.173),
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import builtins
|
||||
# Also, I'm not sure multiple camera-group configurations are working for the
|
||||
# cluster system.
|
||||
|
||||
|
||||
class ClusterServer(DirectObject.DirectObject):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("ClusterServer")
|
||||
MSG_NUM = 2000000
|
||||
@@ -101,8 +102,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
clusterDaemonPort = CLUSTER_DAEMON_PORT
|
||||
self.daemon.serverReady(clusterDaemonClient, clusterDaemonPort)
|
||||
|
||||
|
||||
|
||||
def startListenerPollTask(self):
|
||||
# Run this task near the start of frame, sometime after the dataLoop
|
||||
taskMgr.add(self.listenerPollTask, "serverListenerPollTask", -40)
|
||||
@@ -125,7 +124,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
self.notify.warning("getNewConnection returned false")
|
||||
return Task.cont
|
||||
|
||||
|
||||
def addNamedObjectMapping(self, object, name, hasColor = True,
|
||||
priority = 0):
|
||||
if name not in self.objectMappings:
|
||||
@@ -138,7 +136,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
if name in self.objectMappings:
|
||||
self.objectMappings.pop(name)
|
||||
|
||||
|
||||
def redoSortedPriorities(self):
|
||||
|
||||
self.sortedControlMappings = []
|
||||
@@ -148,7 +145,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
|
||||
self.sortedControlMappings.sort()
|
||||
|
||||
|
||||
def addControlMapping(self, objectName, controlledName, offset = None,
|
||||
priority = 0):
|
||||
if objectName not in self.controlMappings:
|
||||
@@ -165,14 +161,12 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
if objectName in self.controlMappings:
|
||||
self.controlOffsets[objectName] = offset
|
||||
|
||||
|
||||
def removeControlMapping(self, name):
|
||||
if name in self.controlMappings:
|
||||
self.controlMappings.pop(name)
|
||||
self.controlPriorities.pop(name)
|
||||
self.redoSortedPriorities()
|
||||
|
||||
|
||||
def startControlObjectTask(self):
|
||||
self.notify.debug("moving control objects")
|
||||
taskMgr.add(self.controlObjectTask,"controlObjectTask",50)
|
||||
@@ -189,7 +183,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
self.sendNamedMovementDone()
|
||||
return Task.cont
|
||||
|
||||
|
||||
def sendNamedMovementDone(self):
|
||||
self.notify.debug("named movement done")
|
||||
datagram = self.msgHandler.makeNamedMovementDone()
|
||||
@@ -333,7 +326,6 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
else:
|
||||
self.notify.debug("recieved unknown named object command: "+name)
|
||||
|
||||
|
||||
def handleMessageQueue(self):
|
||||
#print(self.messageQueue)
|
||||
for data in self.messageQueue:
|
||||
@@ -369,5 +361,5 @@ class ClusterServer(DirectObject.DirectObject):
|
||||
command = self.msgHandler.parseCommandStringDatagram(dgi)
|
||||
try:
|
||||
exec(command, __builtins__)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -41,8 +41,6 @@ class ControlManager:
|
||||
#self.monitorTask = taskMgr.add(self.monitor, "ControlManager-%s"%(id(self)), priority=-1)
|
||||
self.forceAvJumpToken = None
|
||||
|
||||
|
||||
|
||||
if self.passMessagesThrough: # for not breaking toontown
|
||||
ist=self.inputStateTokens
|
||||
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
|
||||
@@ -50,7 +48,6 @@ class ControlManager:
|
||||
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
|
||||
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return 'ControlManager: using \'%s\'' % self.currentControlsName
|
||||
|
||||
@@ -325,7 +322,7 @@ class ControlManager:
|
||||
self.WASDTurnTokens = (
|
||||
inputState.watchWithModifiers("turnLeft", "a", inputSource=inputState.WASD),
|
||||
inputState.watchWithModifiers("turnRight", "d", inputSource=inputState.WASD),
|
||||
)
|
||||
)
|
||||
|
||||
inputState.set("turnLeft", slideLeftWASDSet, inputSource=inputState.WASD)
|
||||
inputState.set("turnRight", slideRightWASDSet, inputSource=inputState.WASD)
|
||||
@@ -337,7 +334,7 @@ class ControlManager:
|
||||
self.WASDTurnTokens = (
|
||||
inputState.watchWithModifiers("slideLeft", "a", inputSource=inputState.WASD),
|
||||
inputState.watchWithModifiers("slideRight", "d", inputSource=inputState.WASD),
|
||||
)
|
||||
)
|
||||
|
||||
inputState.set("slideLeft", turnLeftWASDSet, inputSource=inputState.WASD)
|
||||
inputState.set("slideRight", turnRightWASDSet, inputSource=inputState.WASD)
|
||||
|
||||
@@ -8,36 +8,47 @@ from direct.showbase.MessengerGlobal import messenger
|
||||
class InputStateToken:
|
||||
_SerialGen = SerialNumGen()
|
||||
Inval = 'invalidatedToken'
|
||||
|
||||
def __init__(self, inputState):
|
||||
self._id = InputStateToken._SerialGen.next()
|
||||
self._hash = self._id
|
||||
self._inputState = inputState
|
||||
|
||||
def release(self):
|
||||
# subclasses will override
|
||||
assert False
|
||||
|
||||
def isValid(self):
|
||||
return self._id != InputStateToken.Inval
|
||||
|
||||
def invalidate(self):
|
||||
self._id = InputStateToken.Inval
|
||||
|
||||
def __hash__(self):
|
||||
return self._hash
|
||||
|
||||
#snake_case alias:
|
||||
is_valid = isValid
|
||||
|
||||
|
||||
class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
|
||||
def release(self):
|
||||
self._inputState._ignore(self)
|
||||
self.ignoreAll()
|
||||
|
||||
|
||||
class InputStateForceToken(InputStateToken):
|
||||
def release(self):
|
||||
self._inputState._unforce(self)
|
||||
|
||||
|
||||
class InputStateTokenGroup:
|
||||
def __init__(self):
|
||||
self._tokens = []
|
||||
|
||||
def addToken(self, token):
|
||||
self._tokens.append(token)
|
||||
|
||||
def release(self):
|
||||
for token in self._tokens:
|
||||
token.release()
|
||||
@@ -46,6 +57,7 @@ class InputStateTokenGroup:
|
||||
#snake_case alias:
|
||||
add_token = addToken
|
||||
|
||||
|
||||
class InputState(DirectObject.DirectObject):
|
||||
"""
|
||||
InputState is for tracking the on/off state of some events.
|
||||
@@ -190,7 +202,6 @@ class InputState(DirectObject.DirectObject):
|
||||
# input state simply because we're not looking at it anymore.
|
||||
# self.set(name, False, inputSource)
|
||||
|
||||
|
||||
def force(self, name, value, inputSource):
|
||||
"""
|
||||
Force isSet(name) to return 'value'.
|
||||
@@ -213,7 +224,7 @@ class InputState(DirectObject.DirectObject):
|
||||
self.notify.error(
|
||||
"%s is trying to force '%s' to ON, but '%s' is already being forced OFF by %s" %
|
||||
(inputSource, name, name, self._forcingOff[name])
|
||||
)
|
||||
)
|
||||
self._forcingOn.setdefault(name, set())
|
||||
self._forcingOn[name].add(inputSource)
|
||||
else:
|
||||
@@ -221,7 +232,7 @@ class InputState(DirectObject.DirectObject):
|
||||
self.notify.error(
|
||||
"%s is trying to force '%s' to OFF, but '%s' is already being forced ON by %s" %
|
||||
(inputSource, name, name, self._forcingOn[name])
|
||||
)
|
||||
)
|
||||
self._forcingOff.setdefault(name, set())
|
||||
self._forcingOff[name].add(inputSource)
|
||||
return token
|
||||
|
||||
@@ -55,6 +55,7 @@ import math
|
||||
|
||||
#import LineStream
|
||||
|
||||
|
||||
class PhysicsWalker(DirectObject.DirectObject):
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("PhysicsWalker")
|
||||
@@ -546,7 +547,7 @@ class PhysicsWalker(DirectObject.DirectObject):
|
||||
onScreenDebug.add("highMark", "% 10.4f"%(self.highMark,))
|
||||
#if airborneHeight < 0.1: #contact!=Vec3.zero():
|
||||
if (airborneHeight > self.avatarRadius*0.5
|
||||
or physObject.getVelocity().getZ() > 0.0
|
||||
or physObject.getVelocity().getZ() > 0.0
|
||||
): # Check stair angles before changing this.
|
||||
# ...the avatar is airborne (maybe a lot or a tiny amount).
|
||||
self.isAirborne = 1
|
||||
|
||||
@@ -35,6 +35,7 @@ JOYBOX_RANGE = JOYBOX_MAX - JOYBOX_MIN
|
||||
|
||||
JOYBOX_TREAD_SEPERATION = 1.0
|
||||
|
||||
|
||||
class DirectJoybox(DirectObject):
|
||||
joyboxCount = 0
|
||||
xyzMultiplier = 1.0
|
||||
@@ -87,12 +88,10 @@ class DirectJoybox(DirectObject):
|
||||
# Spawn update task
|
||||
self.enable()
|
||||
|
||||
|
||||
def setHeadingNodePath(self,np):
|
||||
|
||||
self.headingNP = np
|
||||
|
||||
|
||||
def enable(self):
|
||||
# Kill existing task
|
||||
self.disable()
|
||||
@@ -126,18 +125,25 @@ class DirectJoybox(DirectObject):
|
||||
|
||||
def getNodePath(self):
|
||||
return self.nodePath
|
||||
|
||||
def setRefCS(self, refCS):
|
||||
self.refCS = refCS
|
||||
|
||||
def getRefCS(self):
|
||||
return self.refCS
|
||||
|
||||
def getEventName(self, index):
|
||||
return self.name + '-button-' + repr(index)
|
||||
|
||||
def setXyzMultiplier(self, multiplier):
|
||||
DirectJoybox.xyzMultiplier = multiplier
|
||||
|
||||
def getXyzMultiplier(self):
|
||||
return DirectJoybox.xyzMultiplier
|
||||
|
||||
def setHprMultiplier(self, multiplier):
|
||||
DirectJoybox.hprMultiplier = multiplier
|
||||
|
||||
def getHprMultiplier(self):
|
||||
return DirectJoybox.hprMultiplier
|
||||
|
||||
@@ -193,6 +199,7 @@ class DirectJoybox(DirectObject):
|
||||
|
||||
def acceptSwitchModeEvent(self, button = R_UPPER):
|
||||
self.accept(self.getEventName(button), self.switchMode)
|
||||
|
||||
def ignoreSwitchModeEvent(self, button = R_UPPER):
|
||||
self.ignore(self.getEventName(button))
|
||||
|
||||
@@ -208,7 +215,7 @@ class DirectJoybox(DirectObject):
|
||||
pass
|
||||
|
||||
def showMode(self, modeText):
|
||||
def hideText(state, s = self):
|
||||
def hideText(state, s=self):
|
||||
s.readout.setText('')
|
||||
return Task.done
|
||||
taskMgr.remove(self.name + '-showMode')
|
||||
@@ -220,6 +227,7 @@ class DirectJoybox(DirectObject):
|
||||
def acceptUprightCameraEvent(self, button = L_UPPER):
|
||||
self.accept(self.getEventName(button),
|
||||
base.direct.cameraControl.orbitUprightCam)
|
||||
|
||||
def ignoreUprightCameraEvent(self, button = L_UPPER):
|
||||
self.ignore(self.getEventName(button))
|
||||
|
||||
@@ -230,29 +238,29 @@ class DirectJoybox(DirectObject):
|
||||
self.showMode(self.modeName)
|
||||
self.enable()
|
||||
|
||||
|
||||
def setUseHeadingNP(self,enabled):
|
||||
|
||||
def setUseHeadingNP(self, enabled):
|
||||
self.useHeadingNP = enabled
|
||||
|
||||
def setRotateInPlace(self,enabled):
|
||||
|
||||
def setRotateInPlace(self, enabled):
|
||||
self.rotateInPlace = enabled
|
||||
|
||||
def joyboxFly(self):
|
||||
# Do nothing if no nodePath selected
|
||||
if self.nodePath is None:
|
||||
return
|
||||
|
||||
hprScale = ((self.aList[L_SLIDE] + 1.0) *
|
||||
50.0 * DirectJoybox.hprMultiplier)
|
||||
posScale = ((self.aList[R_SLIDE] + 1.0) *
|
||||
50.0 * DirectJoybox.xyzMultiplier)
|
||||
def getAxisVal(index, s = self):
|
||||
|
||||
def getAxisVal(index, s=self):
|
||||
try:
|
||||
return s.aList[s.mapping[index]]
|
||||
except IndexError:
|
||||
# If it is a null axis return 0
|
||||
return 0.0
|
||||
|
||||
x = getAxisVal(0) * self.modifier[0]
|
||||
y = getAxisVal(1) * self.modifier[1]
|
||||
z = getAxisVal(2) * self.modifier[2]
|
||||
@@ -262,13 +270,13 @@ class DirectJoybox(DirectObject):
|
||||
p = getAxisVal(4) * self.modifier[4]
|
||||
r = getAxisVal(5) * self.modifier[5]
|
||||
hpr = Vec3(h, p, r) * (hprScale * self.deltaTime)
|
||||
|
||||
# if we are using a heading nodepath, we want
|
||||
# to drive in the direction we are facing,
|
||||
# however, we don't want the z component to change
|
||||
if self.useHeadingNP and self.headingNP is not None:
|
||||
oldZ = pos.getZ()
|
||||
pos = self.nodePath.getRelativeVector(self.headingNP,
|
||||
pos)
|
||||
pos = self.nodePath.getRelativeVector(self.headingNP, pos)
|
||||
pos.setZ(oldZ)
|
||||
# if we are using a heading NP we might want to rotate
|
||||
# in place around that NP
|
||||
@@ -282,7 +290,6 @@ class DirectJoybox(DirectObject):
|
||||
self.nodePath.wrtReparentTo(parent)
|
||||
hpr = Vec3(0,0,0)
|
||||
|
||||
|
||||
self.nodePath.setPosHpr(self.nodePath, pos, hpr)
|
||||
|
||||
def joeMode(self):
|
||||
@@ -291,25 +298,23 @@ class DirectJoybox(DirectObject):
|
||||
self.modifier = [1, 1, 1, -1, -1, 0]
|
||||
self.setMode(self.joyboxFly, 'Joe Mode')
|
||||
|
||||
|
||||
def basicMode(self):
|
||||
self.mapping = [NULL_AXIS, R_FWD_BACK, NULL_AXIS,
|
||||
R_LEFT_RIGHT, NULL_AXIS, NULL_AXIS]
|
||||
self.modifier = [0,1,0,-1,0,0]
|
||||
self.setMode(self.joyboxFly,'Basic Mode')
|
||||
self.modifier = [0, 1, 0, -1, 0, 0]
|
||||
self.setMode(self.joyboxFly, 'Basic Mode')
|
||||
|
||||
def fpsMode(self):
|
||||
self.mapping = [L_LEFT_RIGHT,R_FWD_BACK,L_FWD_BACK,
|
||||
R_LEFT_RIGHT, NULL_AXIS, NULL_AXIS]
|
||||
self.modifier = [1,1,1,-1,0,0]
|
||||
self.setMode(self.joyboxFly,'FPS Mode')
|
||||
self.modifier = [1, 1, 1, -1, 0, 0]
|
||||
self.setMode(self.joyboxFly, 'FPS Mode')
|
||||
|
||||
def tankMode(self):
|
||||
self.setMode(self.tankFly,'Tank Mode')
|
||||
self.setMode(self.tankFly, 'Tank Mode')
|
||||
|
||||
def nullMode(self):
|
||||
self.setMode(self.nullFly,'Null Mode')
|
||||
|
||||
self.setMode(self.nullFly, 'Null Mode')
|
||||
|
||||
def lucMode(self):
|
||||
self.mapping = [R_LEFT_RIGHT, R_FWD_BACK, L_FWD_BACK,
|
||||
@@ -362,7 +367,6 @@ class DirectJoybox(DirectObject):
|
||||
def spaceMode(self):
|
||||
self.setMode(self.spaceFly, 'Space Mode')
|
||||
|
||||
|
||||
def nullFly(self):
|
||||
return
|
||||
|
||||
@@ -384,10 +388,6 @@ class DirectJoybox(DirectObject):
|
||||
self.nodePath.setH(self.nodePath,dh)
|
||||
self.nodePath.setY(self.nodePath,dy)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def spaceFly(self):
|
||||
# Do nothing if no nodePath selected
|
||||
if self.nodePath is None:
|
||||
@@ -498,9 +498,9 @@ class DirectJoybox(DirectObject):
|
||||
# Restore the original hpr of the orbiter
|
||||
self.nodePath.setHpr(self.tempCS, 0, 0, 0)
|
||||
|
||||
|
||||
# We need to override the DirectAnalog normalizeChannel to
|
||||
# correct the ranges of the two twist axes of the joybox.
|
||||
|
||||
def normalizeChannel(self, chan, minVal = -1, maxVal = 1):
|
||||
try:
|
||||
if chan == L_TWIST or chan == R_TWIST:
|
||||
|
||||
@@ -5,6 +5,7 @@ DirectNotify module: this module contains the DirectNotify class
|
||||
from . import Notifier
|
||||
from . import Logger
|
||||
|
||||
|
||||
class DirectNotify:
|
||||
"""
|
||||
DirectNotify class: this class contains methods for creating
|
||||
@@ -15,7 +16,7 @@ class DirectNotify:
|
||||
"""
|
||||
DirectNotify class keeps a dictionary of Notfiers
|
||||
"""
|
||||
self.__categories = { }
|
||||
self.__categories = {}
|
||||
# create a default log file
|
||||
self.logger = Logger.Logger()
|
||||
|
||||
@@ -100,7 +101,6 @@ class DirectNotify:
|
||||
print("DirectNotify: unknown notify level: " + str(level)
|
||||
+ " for category: " + str(categoryName))
|
||||
|
||||
|
||||
def setDconfigLevels(self):
|
||||
for categoryName in self.getCategories():
|
||||
self.setDconfigLevel(categoryName)
|
||||
|
||||
@@ -65,6 +65,7 @@ def comment(code):
|
||||
else:
|
||||
return ''
|
||||
|
||||
|
||||
def block_comment(code):
|
||||
code = code.strip()
|
||||
|
||||
@@ -77,6 +78,7 @@ def block_comment(code):
|
||||
|
||||
return code
|
||||
|
||||
|
||||
def translateFunctionName(name):
|
||||
if name.startswith("__"):
|
||||
return name
|
||||
@@ -93,6 +95,7 @@ def translateFunctionName(name):
|
||||
new += i[0].upper() + i[1:]
|
||||
return new
|
||||
|
||||
|
||||
def translateTypeName(name, mangle=True):
|
||||
# Equivalent to C++ classNameFromCppName
|
||||
class_name = ""
|
||||
@@ -115,6 +118,7 @@ def translateTypeName(name, mangle=True):
|
||||
|
||||
return class_name
|
||||
|
||||
|
||||
def translated_type_name(type, scoped=True):
|
||||
while interrogate_type_is_wrapped(type):
|
||||
if interrogate_type_is_const(type):
|
||||
@@ -205,7 +209,7 @@ def processFunction(handle, function, isConstructor = False):
|
||||
|
||||
def processType(handle, type):
|
||||
typename = translated_type_name(type, scoped=False)
|
||||
derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
|
||||
derivations = [translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type))]
|
||||
|
||||
if interrogate_type_has_comment(type):
|
||||
print(block_comment(interrogate_type_comment(type)), file=handle)
|
||||
@@ -258,6 +262,7 @@ def processType(handle, type):
|
||||
|
||||
print("};", file=handle)
|
||||
|
||||
|
||||
def processModule(handle, package):
|
||||
print("Processing module %s" % (package))
|
||||
print("namespace %s {" % package, file=handle)
|
||||
|
||||
@@ -14,6 +14,7 @@ CAM_MOVE_DURATION = 1.2
|
||||
COA_MARKER_SF = 0.0075
|
||||
Y_AXIS = Vec3(0, 1, 0)
|
||||
|
||||
|
||||
class DirectCameraControl(DirectObject):
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('DirectCameraControl')
|
||||
@@ -50,7 +51,7 @@ class DirectCameraControl(DirectObject):
|
||||
['DIRECT-mouse2Up', self.mouseFlyStop],
|
||||
['DIRECT-mouse3', self.mouseDollyStart],
|
||||
['DIRECT-mouse3Up', self.mouseDollyStop],
|
||||
]
|
||||
]
|
||||
|
||||
# [gjeon] moved all of the hotkeys to single place for easy remapping
|
||||
## self.keyEvents = [
|
||||
@@ -101,7 +102,7 @@ class DirectCameraControl(DirectObject):
|
||||
['DIRECT-removeManipulateCameraTask', self.removeManipulateCameraTask],
|
||||
['DIRECT-zoomInCam', self.zoomCam, 0.5, t],
|
||||
['DIRECT-zoomOutCam', self.zoomCam, -2.0, t],
|
||||
]
|
||||
]
|
||||
# set this to true to prevent the camera from rolling
|
||||
self.lockRoll = False
|
||||
# NIK - flag to determine whether to use maya camera controls
|
||||
@@ -351,7 +352,7 @@ class DirectCameraControl(DirectObject):
|
||||
else:
|
||||
moveDir = Vec3(Y_AXIS)
|
||||
|
||||
if self.useMayaCamControls : # use maya controls
|
||||
if self.useMayaCamControls: # use maya controls
|
||||
moveDir.assign(moveDir * ((base.direct.dr.mouseDeltaX -1.0 * base.direct.dr.mouseDeltaY)
|
||||
* state.zoomSF))
|
||||
hVal = 0.0
|
||||
@@ -613,7 +614,7 @@ class DirectCameraControl(DirectObject):
|
||||
startColor = Vec4(1, 0, 0, 1),
|
||||
blendType = 'easeInOut'),
|
||||
Func(self.coaMarker.stash)
|
||||
)
|
||||
)
|
||||
self.coaMarkerColorIval.start()
|
||||
|
||||
def homeCam(self):
|
||||
@@ -699,7 +700,6 @@ class DirectCameraControl(DirectObject):
|
||||
name = 'manipulateCamera')
|
||||
self.__startManipulateCamera(ival = ival)
|
||||
|
||||
|
||||
def zoomCam(self, zoomFactor, t):
|
||||
self.__stopManipulateCamera()
|
||||
# Record undo point
|
||||
@@ -769,7 +769,6 @@ class DirectCameraControl(DirectObject):
|
||||
name = 'manipulateCamera')
|
||||
self.__startManipulateCamera(ival = ival)
|
||||
|
||||
|
||||
def swingCamAboutWidget(self, degrees, t):
|
||||
# Remove existing camera manipulation task
|
||||
self.__stopManipulateCamera()
|
||||
@@ -834,7 +833,6 @@ class DirectCameraControl(DirectObject):
|
||||
name = 'manipulateCamera')
|
||||
self.__startManipulateCamera(ival = ival)
|
||||
|
||||
|
||||
def moveToFit(self):
|
||||
# How big is the active widget?
|
||||
widgetScale = base.direct.widget.scalingNode.getScale(render)
|
||||
|
||||
@@ -18,6 +18,7 @@ from .DirectGlobals import Q_EPSILON, UNIT_VEC, ZERO_VEC
|
||||
from .DirectUtil import CLAMP
|
||||
import math
|
||||
|
||||
|
||||
class LineNodePath(NodePath):
|
||||
def __init__(self, parent = None, name = None,
|
||||
thickness = 1.0, colorVec = VBase4(1)):
|
||||
@@ -140,13 +141,16 @@ class LineNodePath(NodePath):
|
||||
##
|
||||
## Given a point in space, and a direction, find the point of intersection
|
||||
## of that ray with a plane at the specified origin, with the specified normal
|
||||
def planeIntersect (lineOrigin, lineDir, planeOrigin, normal):
|
||||
|
||||
|
||||
def planeIntersect(lineOrigin, lineDir, planeOrigin, normal):
|
||||
t = 0
|
||||
offset = planeOrigin - lineOrigin
|
||||
t = offset.dot(normal) / lineDir.dot(normal)
|
||||
hitPt = lineDir * t
|
||||
return hitPt + lineOrigin
|
||||
|
||||
|
||||
def getNearProjectionPoint(nodePath):
|
||||
# Find the position of the projection of the specified node path
|
||||
# on the near plane
|
||||
@@ -158,6 +162,7 @@ def getNearProjectionPoint(nodePath):
|
||||
# Object is coplaner with camera, just return something reasonable
|
||||
return Point3(0, base.direct.dr.near, 0)
|
||||
|
||||
|
||||
def getScreenXY(nodePath):
|
||||
# Where does the node path's projection fall on the near plane
|
||||
nearVec = getNearProjectionPoint(nodePath)
|
||||
@@ -172,6 +177,7 @@ def getScreenXY(nodePath):
|
||||
# Return the resulting value
|
||||
return screenXY
|
||||
|
||||
|
||||
def getCrankAngle(center):
|
||||
# Used to compute current angle of mouse (relative to the coa's
|
||||
# origin) in screen space
|
||||
@@ -179,6 +185,7 @@ def getCrankAngle(center):
|
||||
y = base.direct.dr.mouseY - center[2]
|
||||
return 180 + rad2Deg(math.atan2(y, x))
|
||||
|
||||
|
||||
def relHpr(nodePath, base, h, p, r):
|
||||
# Compute nodePath2newNodePath relative to base coordinate system
|
||||
# nodePath2base
|
||||
@@ -202,6 +209,8 @@ def relHpr(nodePath, base, h, p, r):
|
||||
nodePath.setHpr(hpr)
|
||||
|
||||
# Quaternion interpolation
|
||||
|
||||
|
||||
def qSlerp(startQuat, endQuat, t):
|
||||
startQ = Quat(startQuat)
|
||||
destQuat = Quat(Quat.identQuat())
|
||||
|
||||
@@ -72,7 +72,7 @@ class DirectManipulationControl(DirectObject):
|
||||
['DIRECT-widgetScaleDown', self.scaleWidget, 0.5],
|
||||
['shift-f', self.objectHandles.growToFit],
|
||||
['i', self.plantSelectedNodePath],
|
||||
]
|
||||
]
|
||||
self.defaultSkipFlags = DG.SKIP_HIDDEN | DG.SKIP_BACKFACE
|
||||
self.optionalSkipFlags = 0
|
||||
self.unmovableTagList = []
|
||||
@@ -192,8 +192,8 @@ class DirectManipulationControl(DirectObject):
|
||||
return Task.done
|
||||
|
||||
def watchMouseTask(self, state):
|
||||
if (((abs (state.initX - base.direct.dr.mouseX)) > 0.01) or
|
||||
((abs (state.initY - base.direct.dr.mouseY)) > 0.01)):
|
||||
if (abs(state.initX - base.direct.dr.mouseX) > 0.01 or
|
||||
abs(state.initY - base.direct.dr.mouseY) > 0.01):
|
||||
taskMgr.remove('manip-move-wait')
|
||||
self.mode = 'move'
|
||||
self.manipulateObject()
|
||||
@@ -221,8 +221,8 @@ class DirectManipulationControl(DirectObject):
|
||||
endX = base.direct.dr.mouseX
|
||||
endY = base.direct.dr.mouseY
|
||||
|
||||
if (((abs (endX - startX)) < 0.01) and
|
||||
((abs (endY - startY)) < 0.01)):
|
||||
if (abs(endX - startX) < 0.01 and
|
||||
abs(endY - startY) < 0.01):
|
||||
return
|
||||
|
||||
self.marquee = LineNodePath(base.render2d, 'marquee', 0.5, VBase4(.8, .6, .6, 1))
|
||||
@@ -1056,8 +1056,8 @@ class DirectManipulationControl(DirectObject):
|
||||
self.initScale *
|
||||
(self.objectHandles.getWidgetIntersectPt(
|
||||
self.manipRef, 'y').length() /
|
||||
self.initScaleMag)
|
||||
)
|
||||
self.initScaleMag)
|
||||
)
|
||||
base.direct.widget.setScale(currScale)
|
||||
|
||||
## Utility functions ##
|
||||
@@ -1082,6 +1082,7 @@ class DirectManipulationControl(DirectObject):
|
||||
messenger.send('DIRECT_manipulateObjectCleanup',
|
||||
[base.direct.selected.getSelectedAsList()])
|
||||
|
||||
|
||||
class ObjectHandles(NodePath, DirectObject):
|
||||
def __init__(self, name='objectHandles'):
|
||||
# Initialize the superclass
|
||||
@@ -1754,6 +1755,7 @@ class ObjectHandles(NodePath, DirectObject):
|
||||
|
||||
return self.hitPt
|
||||
|
||||
|
||||
def drawBox(lines, center, sideLength):
|
||||
l = sideLength * 0.5
|
||||
lines.moveTo(center[0] + l, center[1] + l, center[2] + l)
|
||||
|
||||
@@ -26,6 +26,8 @@ COA_ORIGIN = 0
|
||||
COA_CENTER = 1
|
||||
|
||||
# MRM: To do: handle broken node paths in selected and deselected dicts
|
||||
|
||||
|
||||
class DirectNodePath(NodePath):
|
||||
# A node path augmented with info, bounding box, and utility methods
|
||||
def __init__(self, nodePath, bboxColor=None):
|
||||
@@ -65,6 +67,7 @@ class DirectNodePath(NodePath):
|
||||
def getMax(self):
|
||||
return self.bbox.getMax()
|
||||
|
||||
|
||||
class SelectedNodePaths(DirectObject):
|
||||
def __init__(self):
|
||||
self.reset()
|
||||
@@ -445,7 +448,7 @@ class DirectBoundingBox:
|
||||
'Max:\t\t%s\n' % self.vecAsString(self.max) +
|
||||
'Center:\t\t%s\n' % self.vecAsString(self.center) +
|
||||
'Radius:\t\t%.2f' % self.radius
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class SelectionQueue(CollisionHandlerQueue):
|
||||
@@ -588,18 +591,18 @@ class SelectionQueue(CollisionHandlerQueue):
|
||||
# Skip if parented to a camera.
|
||||
pass
|
||||
# Can pick unpickable, use the first visible node
|
||||
elif (skipFlags & DG.SKIP_UNPICKABLE) and\
|
||||
elif (skipFlags & DG.SKIP_UNPICKABLE) and \
|
||||
(nodePath.getName() in self.unpickable):
|
||||
# Skip if in unpickable list
|
||||
pass
|
||||
elif base.direct and\
|
||||
elif base.direct and \
|
||||
((skipFlags & DG.SKIP_WIDGET) and
|
||||
(nodePath.getTag('WidgetName') != base.direct.widget.getName())):
|
||||
(nodePath.getTag('WidgetName') != base.direct.widget.getName())):
|
||||
# Skip if this widget part is not belong to current widget
|
||||
pass
|
||||
elif base.direct and\
|
||||
elif base.direct and \
|
||||
((skipFlags & DG.SKIP_WIDGET) and base.direct.fControl and
|
||||
(nodePath.getName()[2:] == 'ring')):
|
||||
(nodePath.getName()[2:] == 'ring')):
|
||||
# Skip when ununiformly scale in ortho view
|
||||
pass
|
||||
else:
|
||||
@@ -608,6 +611,7 @@ class SelectionQueue(CollisionHandlerQueue):
|
||||
break
|
||||
return self.getCurrentEntry()
|
||||
|
||||
|
||||
class SelectionRay(SelectionQueue):
|
||||
def __init__(self, parentNP = None):
|
||||
if parentNP is None:
|
||||
|
||||
@@ -134,7 +134,6 @@ class DirectSession(DirectObject):
|
||||
for i in range(len(fastrak))[1:]:
|
||||
self.fastrak.append(DirectFastrak.DirectFastrak(fastrak[0] + ':' + fastrak[i]))
|
||||
|
||||
|
||||
self.fControl = 0
|
||||
self.fAlt = 0
|
||||
self.fShift = 0
|
||||
@@ -196,7 +195,7 @@ class DirectSession(DirectObject):
|
||||
['DIRECT-doWrtReparent', self.doWrtReparent],
|
||||
['DIRECT-doReparent', self.doReparent],
|
||||
['DIRECT-doSelect', self.doSelect],
|
||||
]
|
||||
]
|
||||
|
||||
if base.wantTk:
|
||||
from direct.tkpanels import Placer
|
||||
@@ -265,7 +264,7 @@ class DirectSession(DirectObject):
|
||||
'shift-[': ('DIRECT-Undo', 'DIRECT-Undo'),
|
||||
']': ('DIRECT-Redo', 'DIRECT-Redo'),
|
||||
'shift-]': ('DIRECT-Redo', 'DIRECT-Redo'),
|
||||
}
|
||||
}
|
||||
|
||||
self.hotKeyMap = {
|
||||
'c': ('Center Camera', 'DIRECT-centerCamIn'),
|
||||
@@ -293,14 +292,14 @@ class DirectSession(DirectObject):
|
||||
'shift-a': ('Toggle Vis all', 'DIRECT-toggleVisAll'),
|
||||
'w': ('Toggle Wireframe', 'DIRECT-toggleWireframe'),
|
||||
'control-z': ('Undo', 'LE-Undo'),
|
||||
'shift-z' : ('Redo', 'LE-Redo'),
|
||||
'shift-z': ('Redo', 'LE-Redo'),
|
||||
'control-d': ('Duplicate', 'LE-Duplicate'),
|
||||
'control-l': ('Make Live', 'LE-MakeLive'),
|
||||
'control-n': ('New Scene', 'LE-NewScene'),
|
||||
'control-s': ('Save Scene', 'LE-SaveScene'),
|
||||
'control-o': ('Open Scene', 'LE-OpenScene'),
|
||||
'control-q': ('Quit', 'LE-Quit'),
|
||||
}
|
||||
}
|
||||
|
||||
self.speicalKeyMap = {
|
||||
'enter': 'DIRECT-enter',
|
||||
@@ -327,7 +326,6 @@ class DirectSession(DirectObject):
|
||||
self.cluster = DummyClusterClient()
|
||||
__builtins__['cluster'] = self.cluster
|
||||
|
||||
|
||||
def addPassThroughKey(self,key):
|
||||
|
||||
self.passThroughKeys.append(key)
|
||||
@@ -876,6 +874,7 @@ class DirectSession(DirectObject):
|
||||
# If nothing specified, try selected node path
|
||||
nodePath = self.selected.last
|
||||
base.direct.select(nodePath)
|
||||
|
||||
def fitTask(state, self = self):
|
||||
self.cameraControl.fitOnWidget()
|
||||
return Task.done
|
||||
|
||||
@@ -23,7 +23,7 @@ class Mopath(DirectObject):
|
||||
|
||||
def __init__(self, name = None, fluid = 1, objectToLoad = None, upVectorNodePath = None, reverseUpVector = False):
|
||||
if name is None:
|
||||
name = 'mopath%d' % self.nameIndex
|
||||
name = f'mopath{self.nameIndex}'
|
||||
self.nameIndex = self.nameIndex + 1
|
||||
self.name = name
|
||||
self.fluid = fluid
|
||||
@@ -38,12 +38,12 @@ class Mopath(DirectObject):
|
||||
self.upVectorNodePath = upVectorNodePath
|
||||
self.reverseUpVector = reverseUpVector
|
||||
self.reset()
|
||||
if isinstance( objectToLoad, NodePath ):
|
||||
self.loadNodePath( objectToLoad )
|
||||
elif isinstance( objectToLoad, str ):
|
||||
self.loadFile( objectToLoad )
|
||||
if isinstance(objectToLoad, NodePath):
|
||||
self.loadNodePath(objectToLoad)
|
||||
elif isinstance(objectToLoad, str):
|
||||
self.loadFile(objectToLoad)
|
||||
elif objectToLoad is not None:
|
||||
print("Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad)
|
||||
print(f"Mopath: Unable to load object '{objectToLoad}', objectToLoad must be a file name string or a NodePath")
|
||||
|
||||
def getMaxT(self):
|
||||
return self.maxT * self.timeScale
|
||||
@@ -70,7 +70,6 @@ class Mopath(DirectObject):
|
||||
else:
|
||||
print('Mopath: no valid curves in nodePath: %s' % nodePath)
|
||||
|
||||
|
||||
def reset(self):
|
||||
self.maxT = 0.0
|
||||
self.loop = 0
|
||||
|
||||
Vendored
+59
-58
@@ -275,32 +275,32 @@ class CompilationEnvironment:
|
||||
|
||||
def compileExe(self, filename, basename, extraLink=[]):
|
||||
compile = self.compileObjExe % dict({
|
||||
'python' : self.Python,
|
||||
'MSVC' : self.MSVC,
|
||||
'PSDK' : self.PSDK,
|
||||
'suffix64' : self.suffix64,
|
||||
'MD' : self.MD,
|
||||
'pythonIPath' : self.PythonIPath,
|
||||
'pythonVersion' : self.PythonVersion,
|
||||
'arch' : self.arch,
|
||||
'filename' : filename,
|
||||
'basename' : basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
'python': self.Python,
|
||||
'MSVC': self.MSVC,
|
||||
'PSDK': self.PSDK,
|
||||
'suffix64': self.suffix64,
|
||||
'MD': self.MD,
|
||||
'pythonIPath': self.PythonIPath,
|
||||
'pythonVersion': self.PythonVersion,
|
||||
'arch': self.arch,
|
||||
'filename': filename,
|
||||
'basename': basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
sys.stderr.write(compile + '\n')
|
||||
if os.system(compile) != 0:
|
||||
raise Exception('failed to compile %s.' % basename)
|
||||
|
||||
link = self.linkExe % dict({
|
||||
'python' : self.Python,
|
||||
'MSVC' : self.MSVC,
|
||||
'PSDK' : self.PSDK,
|
||||
'suffix64' : self.suffix64,
|
||||
'pythonIPath' : self.PythonIPath,
|
||||
'pythonVersion' : self.PythonVersion,
|
||||
'arch' : self.arch,
|
||||
'filename' : filename,
|
||||
'basename' : basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
'python': self.Python,
|
||||
'MSVC': self.MSVC,
|
||||
'PSDK': self.PSDK,
|
||||
'suffix64': self.suffix64,
|
||||
'pythonIPath': self.PythonIPath,
|
||||
'pythonVersion': self.PythonVersion,
|
||||
'arch': self.arch,
|
||||
'filename': filename,
|
||||
'basename': basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
link += ' ' + ' '.join(extraLink)
|
||||
sys.stderr.write(link + '\n')
|
||||
if os.system(link) != 0:
|
||||
@@ -308,38 +308,39 @@ class CompilationEnvironment:
|
||||
|
||||
def compileDll(self, filename, basename, extraLink=[]):
|
||||
compile = self.compileObjDll % dict({
|
||||
'python' : self.Python,
|
||||
'MSVC' : self.MSVC,
|
||||
'PSDK' : self.PSDK,
|
||||
'suffix64' : self.suffix64,
|
||||
'MD' : self.MD,
|
||||
'pythonIPath' : self.PythonIPath,
|
||||
'pythonVersion' : self.PythonVersion,
|
||||
'arch' : self.arch,
|
||||
'filename' : filename,
|
||||
'basename' : basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
'python': self.Python,
|
||||
'MSVC': self.MSVC,
|
||||
'PSDK': self.PSDK,
|
||||
'suffix64': self.suffix64,
|
||||
'MD': self.MD,
|
||||
'pythonIPath': self.PythonIPath,
|
||||
'pythonVersion': self.PythonVersion,
|
||||
'arch': self.arch,
|
||||
'filename': filename,
|
||||
'basename': basename,
|
||||
}, **sysconf.get_config_vars())
|
||||
sys.stderr.write(compile + '\n')
|
||||
if os.system(compile) != 0:
|
||||
raise Exception('failed to compile %s.' % basename)
|
||||
|
||||
link = self.linkDll % dict({
|
||||
'python' : self.Python,
|
||||
'MSVC' : self.MSVC,
|
||||
'PSDK' : self.PSDK,
|
||||
'suffix64' : self.suffix64,
|
||||
'pythonIPath' : self.PythonIPath,
|
||||
'pythonVersion' : self.PythonVersion,
|
||||
'arch' : self.arch,
|
||||
'filename' : filename,
|
||||
'basename' : basename,
|
||||
'dllext' : self.dllext,
|
||||
}, **sysconf.get_config_vars())
|
||||
'python': self.Python,
|
||||
'MSVC': self.MSVC,
|
||||
'PSDK': self.PSDK,
|
||||
'suffix64': self.suffix64,
|
||||
'pythonIPath': self.PythonIPath,
|
||||
'pythonVersion': self.PythonVersion,
|
||||
'arch': self.arch,
|
||||
'filename': filename,
|
||||
'basename': basename,
|
||||
'dllext': self.dllext,
|
||||
}, **sysconf.get_config_vars())
|
||||
link += ' ' + ' '.join(extraLink)
|
||||
sys.stderr.write(link + '\n')
|
||||
if os.system(link) != 0:
|
||||
raise Exception('failed to link %s.' % basename)
|
||||
|
||||
|
||||
# The code from frozenmain.c in the Python source repository.
|
||||
frozenMainCode = """
|
||||
/* Python interpreter main program for frozen scripts */
|
||||
@@ -675,7 +676,7 @@ okMissing = [
|
||||
'direct.extensions_native.extensions_darwin', '_manylinux',
|
||||
'collections.Iterable', 'collections.Mapping', 'collections.MutableMapping',
|
||||
'collections.Sequence', 'numpy_distutils', '_winapi',
|
||||
]
|
||||
]
|
||||
|
||||
# Since around macOS 10.15, Apple's codesigning process has become more strict.
|
||||
# Appending data to the end of a Mach-O binary is now explicitly forbidden. The
|
||||
@@ -722,6 +723,7 @@ lc_indices_to_slide = {
|
||||
LC_DATA_IN_CODE: [2],
|
||||
}
|
||||
|
||||
|
||||
class Freezer:
|
||||
class ModuleDef:
|
||||
def __init__(self, moduleName, filename = None,
|
||||
@@ -1141,7 +1143,7 @@ class Freezer:
|
||||
if mdef.implicit and '.' in newName:
|
||||
# For implicit modules, check if the parent is excluded.
|
||||
parentName, baseName = newName.rsplit('.', 1)
|
||||
if parentName in excludeDict :
|
||||
if parentName in excludeDict:
|
||||
mdef = excludeDict[parentName]
|
||||
|
||||
if mdef.exclude:
|
||||
@@ -1182,7 +1184,7 @@ class Freezer:
|
||||
self.__loadModule(mdef)
|
||||
# Since it successfully loaded, it's no longer a guess.
|
||||
mdef.guess = False
|
||||
except:
|
||||
except Exception:
|
||||
# Something went wrong, guess it's not an importable
|
||||
# module.
|
||||
pass
|
||||
@@ -1220,7 +1222,7 @@ class Freezer:
|
||||
|
||||
try:
|
||||
self.__loadModule(self.ModuleDef(modname, implicit=True))
|
||||
except:
|
||||
except Exception:
|
||||
missing.append(modname)
|
||||
|
||||
# Now, any new modules we found get added to the export list.
|
||||
@@ -1596,7 +1598,7 @@ class Freezer:
|
||||
text = programFile % {
|
||||
'moduleDefs': '\n'.join(moduleDefs),
|
||||
'moduleList': '\n'.join(moduleList),
|
||||
}
|
||||
}
|
||||
|
||||
if self.linkExtensionModules and self.extras:
|
||||
# Should we link in extension modules? If so, we write out a new
|
||||
@@ -1697,11 +1699,11 @@ class Freezer:
|
||||
if self.platform.startswith('win'):
|
||||
code += self.frozenDllMainCode
|
||||
initCode = self.mainInitCode % {
|
||||
'frozenMainCode' : code,
|
||||
'programName' : os.path.basename(basename),
|
||||
'dllexport' : dllexport,
|
||||
'dllimport' : dllimport,
|
||||
}
|
||||
'frozenMainCode': code,
|
||||
'programName': os.path.basename(basename),
|
||||
'dllexport': dllexport,
|
||||
'dllimport': dllimport,
|
||||
}
|
||||
if self.platform.startswith('win'):
|
||||
target = basename + '.exe'
|
||||
else:
|
||||
@@ -1716,10 +1718,10 @@ class Freezer:
|
||||
target = basename + '.so'
|
||||
|
||||
initCode = dllInitCode % {
|
||||
'moduleName' : os.path.basename(basename),
|
||||
'dllexport' : dllexport,
|
||||
'dllimport' : dllimport,
|
||||
}
|
||||
'moduleName': os.path.basename(basename),
|
||||
'dllexport': dllexport,
|
||||
'dllimport': dllimport,
|
||||
}
|
||||
compileFunc = self.cenv.compileDll
|
||||
|
||||
self.writeCode(filename, initCode=initCode)
|
||||
@@ -2357,7 +2359,6 @@ class Freezer:
|
||||
def makeForbiddenModuleListEntry(self, moduleName):
|
||||
return ' {"%s", NULL, 0},' % (moduleName)
|
||||
|
||||
|
||||
def __writingModule(self, moduleName):
|
||||
""" Returns true if we are outputting the named module in this
|
||||
pass, false if we have already output in a previous pass, or
|
||||
|
||||
Vendored
+4
-2
@@ -28,6 +28,7 @@ def _unpack_zstring(mem, offs=0):
|
||||
c = mem[offs]
|
||||
return str
|
||||
|
||||
|
||||
def _unpack_wstring(mem, offs=0):
|
||||
"Read a UCS-2 string from memory."
|
||||
name_len, = unpack('<H', mem[offs:offs+2])
|
||||
@@ -37,6 +38,7 @@ def _unpack_wstring(mem, offs=0):
|
||||
name += chr(*unpack('<H', mem[offs:offs+2]))
|
||||
return name
|
||||
|
||||
|
||||
def _padded(n, boundary):
|
||||
align = n % boundary
|
||||
if align:
|
||||
@@ -250,11 +252,11 @@ class VersionInfoResource(object):
|
||||
self.struct_version = dwords[1]
|
||||
if len(dwords) > 3:
|
||||
self.file_version = \
|
||||
(int(dwords[2] >> 16), int(dwords[2] & 0xffff),
|
||||
(int(dwords[2] >> 16), int(dwords[2] & 0xffff),
|
||||
int(dwords[3] >> 16), int(dwords[3] & 0xffff))
|
||||
if len(dwords) > 5:
|
||||
self.product_version = \
|
||||
(int(dwords[4] >> 16), int(dwords[4] & 0xffff),
|
||||
(int(dwords[4] >> 16), int(dwords[4] & 0xffff),
|
||||
int(dwords[5] >> 16), int(dwords[5] & 0xffff))
|
||||
if len(dwords) > 7:
|
||||
self.file_flags_mask = dwords[6]
|
||||
|
||||
@@ -122,7 +122,7 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
|
||||
def _getMsgName(self, msgId):
|
||||
# we might get a list of message names, use the first one
|
||||
return makeList(MsgId2Names.get(msgId, 'UNKNOWN MESSAGE: %s' % msgId))[0]
|
||||
return makeList(MsgId2Names.get(msgId, f'UNKNOWN MESSAGE: {msgId}'))[0]
|
||||
|
||||
def allocateContext(self):
|
||||
self.context+=1
|
||||
@@ -161,7 +161,7 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
# Look up the dclass
|
||||
assert parentId == self.GameGlobalsId or parentId in self.doId2do
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
assert self.notify.debug("performing generate for %s %s" % (dclass.getName(), doId))
|
||||
assert self.notify.debug(f"performing generate for {dclass.getName()} {doId}")
|
||||
dclass.startGenerate()
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId)
|
||||
@@ -360,7 +360,6 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
# updateRequiredOtherFields calls announceGenerate
|
||||
return distObj
|
||||
|
||||
|
||||
def disableDoId(self, doId, ownerView=False):
|
||||
table, cache = self.getTables(ownerView)
|
||||
# Make sure the object exists
|
||||
@@ -442,7 +441,6 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
# This object has been fully generated. It's OK to update.
|
||||
self.__doUpdate(doId, di, ovUpdated)
|
||||
|
||||
|
||||
def __doUpdate(self, doId, di, ovUpdated):
|
||||
# Find the DO
|
||||
do = self.doId2do.get(doId)
|
||||
@@ -463,13 +461,12 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
if handle:
|
||||
dclass = self.dclassesByName[handle.dclassName]
|
||||
dclass.receiveUpdate(handle, di)
|
||||
|
||||
else:
|
||||
self.notify.warning(
|
||||
"Asked to update non-existent DistObj " + str(doId))
|
||||
except:
|
||||
f"Asked to update non-existent DistObj {doId}")
|
||||
except Exception:
|
||||
self.notify.warning(
|
||||
"Asked to update non-existent DistObj " + str(doId) + "and failed to find it")
|
||||
f"Asked to update non-existent DistObj {doId} and failed to find it")
|
||||
|
||||
def __doUpdateOwner(self, doId, di):
|
||||
ovObj = self.doId2ownerView.get(doId)
|
||||
@@ -488,7 +485,7 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
self.bootedText = di.getString()
|
||||
|
||||
self.notify.warning(
|
||||
"Server is booting us out (%d): %s" % (self.bootedIndex, self.bootedText))
|
||||
f"Server is booting us out ({self.bootedIndex}): {self.bootedText}")
|
||||
else:
|
||||
self.bootedIndex = None
|
||||
self.bootedText = None
|
||||
@@ -536,7 +533,6 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
doDict[doId] = do
|
||||
return doDict
|
||||
|
||||
|
||||
def considerHeartbeat(self):
|
||||
"""Send a heartbeat message if we haven't sent one recently."""
|
||||
if not self.heartbeatStarted:
|
||||
@@ -566,7 +562,7 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
|
||||
def waitForNextHeartBeat(self):
|
||||
taskMgr.doMethodLater(self.heartbeatInterval, self.sendHeartbeatTask,
|
||||
"heartBeat", taskChain = 'net')
|
||||
"heartBeat", taskChain='net')
|
||||
|
||||
def replaceMethod(self, oldMethod, newFunction):
|
||||
return 0
|
||||
|
||||
@@ -13,6 +13,7 @@ import gc
|
||||
|
||||
__all__ = ["ConnectionRepository", "GCTrigger"]
|
||||
|
||||
|
||||
class ConnectionRepository(
|
||||
DoInterestManager, DoCollectionManager, CConnectionRepository):
|
||||
"""
|
||||
@@ -233,7 +234,7 @@ class ConnectionRepository(
|
||||
distObj.parentId = 0
|
||||
distObj.zoneId = 0
|
||||
# updateRequiredFields calls announceGenerate
|
||||
return distObj
|
||||
return distObj
|
||||
|
||||
def readDCFile(self, dcFileNames = None):
|
||||
"""
|
||||
@@ -589,7 +590,7 @@ class ConnectionRepository(
|
||||
if self.http is None:
|
||||
try:
|
||||
self.http = HTTPClient()
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return self.http
|
||||
@@ -667,6 +668,7 @@ class ConnectionRepository(
|
||||
def uniqueName(self, idString):
|
||||
return "%s-%s" % (idString, self.uniqueId)
|
||||
|
||||
|
||||
class GCTrigger:
|
||||
# used to trigger garbage collection
|
||||
pass
|
||||
|
||||
@@ -24,7 +24,7 @@ ESNum2Str = {
|
||||
ESDisabled: 'ESDisabled',
|
||||
ESGenerating: 'ESGenerating',
|
||||
ESGenerated: 'ESGenerated',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DistributedObject(DistributedObjectBase):
|
||||
@@ -240,7 +240,6 @@ class DistributedObject(DistributedObjectBase):
|
||||
"""
|
||||
assert self.notify.debug('announceGenerate(): %s' % (self.doId))
|
||||
|
||||
|
||||
def _deactivateDO(self):
|
||||
# after this is called, the object is no longer an active DistributedObject
|
||||
# and it may be placed in the cache
|
||||
@@ -324,9 +323,9 @@ class DistributedObject(DistributedObjectBase):
|
||||
"""
|
||||
return self.doId
|
||||
|
||||
|
||||
#This message was moved out of announce generate
|
||||
#to avoid ordering issues.
|
||||
|
||||
def postGenerateMessage(self):
|
||||
if self.activeState != ESGenerated:
|
||||
self.activeState = ESGenerated
|
||||
|
||||
@@ -36,6 +36,8 @@ PredictionLag = ConfigVariableDouble("smooth-prediction-lag", 0.0)
|
||||
|
||||
GlobalSmoothing = 0
|
||||
GlobalPrediction = 0
|
||||
|
||||
|
||||
def globalActivateSmoothing(smoothing, prediction):
|
||||
""" Globally activates or deactivates smoothing and prediction on
|
||||
all DistributedSmoothNodes currently in existence, or yet to be
|
||||
@@ -48,6 +50,7 @@ def globalActivateSmoothing(smoothing, prediction):
|
||||
for obj in base.cr.getAllOfType(DistributedSmoothNode):
|
||||
obj.activateSmoothing(smoothing, prediction)
|
||||
|
||||
|
||||
# For historical reasons, we temporarily define
|
||||
# DistributedSmoothNode.activateSmoothing() to be the global function.
|
||||
# We'll remove this soon, so it won't get confused with the instance
|
||||
@@ -154,6 +157,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
|
||||
def setSmoothWrtReparents(self, flag):
|
||||
self._smoothWrtReparents = flag
|
||||
|
||||
def getSmoothWrtReparents(self):
|
||||
return self._smoothWrtReparents
|
||||
|
||||
@@ -213,42 +217,50 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
def setSmStop(self, timestamp=None):
|
||||
self.setComponentTLive(timestamp)
|
||||
self.stopped = True
|
||||
|
||||
def setSmH(self, h, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmZ(self, z, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmXY(self, x, y, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmXZ(self, x, z, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmPos(self, x, y, z, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmHpr(self, h, p, r, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentH(h)
|
||||
self.setComponentP(p)
|
||||
self.setComponentR(r)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmXYH(self, x, y, h, timestamp):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmXYZH(self, x, y, z, h, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
@@ -256,6 +268,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
self.setComponentZ(z)
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def setSmPosHpr(self, x, y, z, h, p, r, timestamp=None):
|
||||
self._checkResume(timestamp)
|
||||
self.setComponentX(x)
|
||||
@@ -285,26 +298,33 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentX(self, x):
|
||||
self.smoother.setX(x)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentY(self, y):
|
||||
self.smoother.setY(y)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentZ(self, z):
|
||||
self.smoother.setZ(z)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentH(self, h):
|
||||
self.smoother.setH(h)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentP(self, p):
|
||||
self.smoother.setP(p)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentR(self, r):
|
||||
self.smoother.setR(r)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentL(self, l):
|
||||
if l != self.zoneId:
|
||||
# only perform set location if location is different
|
||||
self.setLocation(self.parentId,l)
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def setComponentT(self, timestamp):
|
||||
# This is a little bit hacky. If *this* function is called,
|
||||
@@ -387,18 +407,25 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
# match set* in more cases than the Disney server does.
|
||||
def getComponentL(self):
|
||||
return self.zoneId
|
||||
|
||||
def getComponentX(self):
|
||||
return self.getX()
|
||||
|
||||
def getComponentY(self):
|
||||
return self.getY()
|
||||
|
||||
def getComponentZ(self):
|
||||
return self.getZ()
|
||||
|
||||
def getComponentH(self):
|
||||
return self.getH()
|
||||
|
||||
def getComponentP(self):
|
||||
return self.getP()
|
||||
|
||||
def getComponentR(self):
|
||||
return self.getR()
|
||||
|
||||
def getComponentT(self):
|
||||
return 0
|
||||
|
||||
@@ -409,7 +436,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
#printStack()
|
||||
self.smoother.clearPositions(1)
|
||||
|
||||
|
||||
@report(types = ['args'], dConfigParam = 'smoothnode')
|
||||
def wrtReparentTo(self, parent):
|
||||
# We override this NodePath method to force it to
|
||||
@@ -476,7 +502,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
serverTime,
|
||||
globalClockDelta.getUncertainty())
|
||||
|
||||
|
||||
def d_returnResync(self, avId, timestampB, serverTime, uncertainty):
|
||||
serverTimeSec = math.floor(serverTime)
|
||||
serverTimeUSec = (serverTime - serverTimeSec) * 10000.0
|
||||
@@ -484,7 +509,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
avId, timestampB, serverTimeSec, serverTimeUSec, uncertainty])
|
||||
|
||||
def returnResync(self, avId, timestampB, serverTimeSec, serverTimeUSec,
|
||||
uncertainty):
|
||||
uncertainty):
|
||||
"""
|
||||
A reply sent by a client whom we recently sent suggestResync
|
||||
to, this reports the client's new delta information so we can
|
||||
|
||||
@@ -13,8 +13,10 @@ class DummyTaskClass:
|
||||
def setDelay(self, blah):
|
||||
pass
|
||||
|
||||
|
||||
DummyTask = DummyTaskClass()
|
||||
|
||||
|
||||
class DistributedSmoothNodeBase:
|
||||
"""common base class for DistributedSmoothNode and DistributedSmoothNodeAI
|
||||
"""
|
||||
@@ -43,6 +45,7 @@ class DistributedSmoothNodeBase:
|
||||
def b_clearSmoothing(self):
|
||||
self.d_clearSmoothing()
|
||||
self.clearSmoothing()
|
||||
|
||||
def d_clearSmoothing(self):
|
||||
self.sendUpdate("clearSmoothing", [0])
|
||||
|
||||
@@ -85,7 +88,7 @@ class DistributedSmoothNodeBase:
|
||||
BT.FULL: self.cnode.broadcastPosHprFull,
|
||||
BT.XYH: self.cnode.broadcastPosHprXyh,
|
||||
BT.XY: self.cnode.broadcastPosHprXy,
|
||||
}
|
||||
}
|
||||
# this comment is here so it will show up in a grep for 'def d_broadcastPosHpr'
|
||||
self.d_broadcastPosHpr = broadcastFuncs[self.broadcastType]
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ MsgName2Id = {
|
||||
'CLIENTAGENT_ADD_INTEREST': 1200,
|
||||
'CLIENTAGENT_ADD_INTEREST_MULTIPLE': 1201,
|
||||
'CLIENTAGENT_REMOVE_INTEREST': 1203,
|
||||
}
|
||||
}
|
||||
|
||||
# create id->name table for debugging
|
||||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
@@ -157,7 +157,7 @@ QUIET_ZONE_IGNORED_LIST = [
|
||||
#CLIENT_CREATE_OBJECT_REQUIRED,
|
||||
#CLIENT_CREATE_OBJECT_REQUIRED_OTHER,
|
||||
|
||||
]
|
||||
]
|
||||
|
||||
# The following is a different set of numbers from above.
|
||||
# These are the sub-message types for CLIENT_LOGIN_2.
|
||||
|
||||
@@ -20,7 +20,7 @@ MsgName2Id = {
|
||||
'CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU' : 9011,
|
||||
|
||||
'CLIENT_OBJECT_UPDATE_FIELD' : 120, # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD
|
||||
}
|
||||
}
|
||||
|
||||
# create id->name table for debugging
|
||||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
|
||||
@@ -48,7 +48,7 @@ class PyDatagram(Datagram):
|
||||
STString: (Datagram.addString, None),
|
||||
STBlob: (Datagram.addBlob, None),
|
||||
STBlob32: (Datagram.addBlob32, None),
|
||||
}
|
||||
}
|
||||
|
||||
addChannel = Datagram.addUint64
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class PyDatagramIterator(DatagramIterator):
|
||||
STString: DatagramIterator.getString,
|
||||
STBlob: DatagramIterator.getBlob,
|
||||
STBlob32: DatagramIterator.getBlob32,
|
||||
}
|
||||
}
|
||||
|
||||
getChannel = DatagramIterator.getUint64
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ class CommonFilters:
|
||||
text += "{\n"
|
||||
text += " o_color = tex2D(k_txcolor, %s);\n" % (texcoords["color"])
|
||||
if "CartoonInk" in configuration:
|
||||
text += CARTOON_BODY % {"texcoord" : texcoords["aux"]}
|
||||
text += CARTOON_BODY % {"texcoord": texcoords["aux"]}
|
||||
if "AmbientOcclusion" in configuration:
|
||||
text += " o_color *= tex2D(k_txssao2, %s).r;\n" % (texcoords["ssao2"])
|
||||
if "BlurSharpen" in configuration:
|
||||
|
||||
@@ -150,7 +150,6 @@ class ClassicFSM(DirectObject):
|
||||
def getCurrentState(self):
|
||||
return self.__currentState
|
||||
|
||||
|
||||
# lookup funcs
|
||||
|
||||
def getStateNamed(self, stateName):
|
||||
@@ -315,7 +314,6 @@ class ClassicFSM(DirectObject):
|
||||
ClassicFSM.notify.warning(msg)
|
||||
return 0
|
||||
|
||||
|
||||
def forceTransition(self, aStateName, enterArgList=[], exitArgList=[]):
|
||||
"""
|
||||
force a transition -- for debugging ONLY
|
||||
@@ -355,7 +353,7 @@ class ClassicFSM(DirectObject):
|
||||
self.__currentState.isTransitionDefined(aStateName) or
|
||||
aStateName in [self.__currentState.getName(),
|
||||
self.__finalState.getName()]
|
||||
)
|
||||
)
|
||||
|
||||
if transitionDefined:
|
||||
return self.request(aStateName, enterArgList, exitArgList)
|
||||
|
||||
@@ -115,7 +115,7 @@ class FourState:
|
||||
self.enterState4,
|
||||
self.exitState4,
|
||||
[names[1]]),
|
||||
}
|
||||
}
|
||||
self.fsm = ClassicFSM.ClassicFSM('FourState',
|
||||
list(self.states.values()),
|
||||
# Initial State
|
||||
|
||||
@@ -123,7 +123,7 @@ class FourStateAI:
|
||||
self.enterState4,
|
||||
self.exitState4,
|
||||
[names[1]]),
|
||||
}
|
||||
}
|
||||
self.fsm = ClassicFSM.ClassicFSM('FourState',
|
||||
list(self.states.values()),
|
||||
# Initial State
|
||||
|
||||
@@ -16,7 +16,7 @@ class ClassicStyle(FSM.FSM):
|
||||
'Red': ['Green'],
|
||||
'Yellow': ['Red'],
|
||||
'Green': ['Yellow'],
|
||||
}
|
||||
}
|
||||
|
||||
def enterRed(self):
|
||||
print("enterRed(self, '%s', '%s')" % (self.oldState, self.newState))
|
||||
|
||||
@@ -10,11 +10,13 @@ from panda3d.core import Mat4, MouseButton, PGButton
|
||||
from . import DirectGuiGlobals as DGG
|
||||
from .DirectFrame import DirectFrame
|
||||
|
||||
|
||||
class DirectButton(DirectFrame):
|
||||
"""
|
||||
DirectButton(parent) - Create a DirectGuiWidget which responds
|
||||
to mouse clicks and execute a callback function if defined
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
# A Direct Frame can have:
|
||||
@@ -45,7 +47,7 @@ class DirectButton(DirectFrame):
|
||||
# Can only be specified at time of widget contruction
|
||||
# Do the text/graphics appear to move when the button is clicked
|
||||
('pressEffect', 1, DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ class DirectCheckBox(DirectButton):
|
||||
|
||||
Uses an image swap rather than a text change to indicate state.
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
|
||||
optiondefs = (
|
||||
@@ -33,7 +34,7 @@ class DirectCheckBox(DirectButton):
|
||||
('uncheckedImage', None, None),
|
||||
('checkedImage', None, None),
|
||||
('isChecked', False, None),
|
||||
)
|
||||
)
|
||||
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
@@ -42,7 +43,6 @@ class DirectCheckBox(DirectButton):
|
||||
|
||||
self.initialiseoptions(DirectCheckBox)
|
||||
|
||||
|
||||
def commandFunc(self, event):
|
||||
self['isChecked'] = not self['isChecked']
|
||||
|
||||
|
||||
@@ -12,12 +12,14 @@ from panda3d.core import PGFrameStyle, VBase4
|
||||
from .DirectButton import DirectButton
|
||||
from .DirectLabel import DirectLabel
|
||||
|
||||
|
||||
class DirectCheckButton(DirectButton):
|
||||
"""
|
||||
DirectCheckButton(parent) - Create a DirectGuiWidget which responds
|
||||
to mouse clicks by setting a state of on or off and execute a callback
|
||||
function (passing that state through) if defined
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectButton
|
||||
# A Direct Frame can have:
|
||||
@@ -42,7 +44,7 @@ class DirectCheckButton(DirectButton):
|
||||
('boxImageScale', 1, None),
|
||||
('boxImageColor', None, None),
|
||||
('boxRelief', 'sunken', None),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
# Initialize superclasses
|
||||
@@ -167,7 +169,6 @@ class DirectCheckButton(DirectButton):
|
||||
|
||||
self.indicator.setPos(newpos[0], newpos[1], newpos[2])
|
||||
|
||||
|
||||
def commandFunc(self, event):
|
||||
self['indicatorValue'] = 1 - self['indicatorValue']
|
||||
if self.colors is not None:
|
||||
|
||||
@@ -120,7 +120,7 @@ class DirectDialog(DirectFrame):
|
||||
('command', None, None),
|
||||
('extraArgs', [], None),
|
||||
('sortOrder', DGG.NO_FADE_SORT_INDEX, None),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs, dynamicGroups = ("button",))
|
||||
|
||||
@@ -178,7 +178,7 @@ class DirectDialog(DirectFrame):
|
||||
suppressKeys = self['suppressKeys'],
|
||||
frameSize = self['buttonSize'],
|
||||
command = lambda s = self, v = value: s.buttonCommand(v)
|
||||
)
|
||||
)
|
||||
self.buttonList.append(button)
|
||||
|
||||
# Update dialog when everything has been initialised
|
||||
@@ -356,6 +356,7 @@ class DirectDialog(DirectFrame):
|
||||
button.destroy()
|
||||
DirectFrame.destroy(self)
|
||||
|
||||
|
||||
class OkDialog(DirectDialog):
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
@@ -363,12 +364,13 @@ class OkDialog(DirectDialog):
|
||||
# Define type of DirectGuiWidget
|
||||
('buttonTextList', ['OK'], DGG.INITOPT),
|
||||
('buttonValueList', [DGG.DIALOG_OK], DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectDialog.__init__(self, parent)
|
||||
self.initialiseoptions(OkDialog)
|
||||
|
||||
|
||||
class OkCancelDialog(DirectDialog):
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
@@ -376,12 +378,13 @@ class OkCancelDialog(DirectDialog):
|
||||
# Define type of DirectGuiWidget
|
||||
('buttonTextList', ['OK','Cancel'], DGG.INITOPT),
|
||||
('buttonValueList', [DGG.DIALOG_OK, DGG.DIALOG_CANCEL], DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectDialog.__init__(self, parent)
|
||||
self.initialiseoptions(OkCancelDialog)
|
||||
|
||||
|
||||
class YesNoDialog(DirectDialog):
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
@@ -389,12 +392,13 @@ class YesNoDialog(DirectDialog):
|
||||
# Define type of DirectGuiWidget
|
||||
('buttonTextList', ['Yes', 'No'], DGG.INITOPT),
|
||||
('buttonValueList', [DGG.DIALOG_YES, DGG.DIALOG_NO], DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectDialog.__init__(self, parent)
|
||||
self.initialiseoptions(YesNoDialog)
|
||||
|
||||
|
||||
class YesNoCancelDialog(DirectDialog):
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
@@ -403,12 +407,13 @@ class YesNoCancelDialog(DirectDialog):
|
||||
('buttonTextList', ['Yes', 'No', 'Cancel'], DGG.INITOPT),
|
||||
('buttonValueList', [DGG.DIALOG_YES, DGG.DIALOG_NO, DGG.DIALOG_CANCEL],
|
||||
DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectDialog.__init__(self, parent)
|
||||
self.initialiseoptions(YesNoCancelDialog)
|
||||
|
||||
|
||||
class RetryCancelDialog(DirectDialog):
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
@@ -416,7 +421,7 @@ class RetryCancelDialog(DirectDialog):
|
||||
# Define type of DirectGuiWidget
|
||||
('buttonTextList', ['Retry','Cancel'], DGG.INITOPT),
|
||||
('buttonValueList', [DGG.DIALOG_RETRY, DGG.DIALOG_CANCEL], DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectDialog.__init__(self, parent)
|
||||
|
||||
@@ -21,6 +21,7 @@ ENTRY_FOCUS_STATE = PGEntry.SFocus # 0
|
||||
ENTRY_NO_FOCUS_STATE = PGEntry.SNoFocus # 1
|
||||
ENTRY_INACTIVE_STATE = PGEntry.SInactive # 2
|
||||
|
||||
|
||||
class DirectEntry(DirectFrame):
|
||||
"""
|
||||
DirectEntry(parent) - Create a DirectGuiWidget which responds
|
||||
@@ -82,7 +83,7 @@ class DirectEntry(DirectFrame):
|
||||
('autoCapitalize', 0, self.autoCapitalizeFunc),
|
||||
('autoCapitalizeAllowPrefixes', DirectEntry.AllowCapNamePrefixes, None),
|
||||
('autoCapitalizeForcePrefixes', DirectEntry.ForceCapNamePrefixes, None),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -215,6 +216,7 @@ class DirectEntry(DirectFrame):
|
||||
|
||||
def _handleTyping(self, guiEvent):
|
||||
self._autoCapitalize()
|
||||
|
||||
def _handleErasing(self, guiEvent):
|
||||
self._autoCapitalize()
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class DirectEntryScroll(DirectFrame):
|
||||
('pgFunc', PGVirtualFrame, None),
|
||||
('relief', None, None),
|
||||
('clipSize', (-1, 1, -1, 1), self.setClipSize),
|
||||
)
|
||||
)
|
||||
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectFrame.__init__(self, parent, **kw)
|
||||
@@ -80,7 +80,6 @@ class DirectEntryScroll(DirectFrame):
|
||||
if abs(distanceToCenter) > (clipExtent * 0.5):
|
||||
self.moveToCenterCursor()
|
||||
|
||||
|
||||
def moveToCenterCursor(self):
|
||||
cursorX = self.entry.guiItem.getCursorX() * self.entry['text_scale'][0]
|
||||
canvasX = self.canvas.getX()
|
||||
@@ -121,7 +120,6 @@ class DirectEntryScroll(DirectFrame):
|
||||
self.entry = None
|
||||
DirectFrame.destroy(self)
|
||||
|
||||
|
||||
def getCanvas(self):
|
||||
return self.canvas
|
||||
|
||||
|
||||
@@ -659,9 +659,11 @@ class DirectGuiBase(DirectObject.DirectObject):
|
||||
gEvent = event + self.guiId
|
||||
self.ignore(gEvent)
|
||||
|
||||
|
||||
def toggleGuiGridSnap():
|
||||
DirectGuiWidget.snapToGrid = 1 - DirectGuiWidget.snapToGrid
|
||||
|
||||
|
||||
def setGuiGridSpacing(spacing):
|
||||
DirectGuiWidget.gridSpacing = spacing
|
||||
|
||||
@@ -722,7 +724,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
|
||||
('suppressMouse', 1, DGG.INITOPT),
|
||||
('suppressKeys', 0, DGG.INITOPT),
|
||||
('enableEdit', 1, DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -829,7 +831,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
|
||||
vMouse2render2d = Point3(event.getMouse()[0], 0, event.getMouse()[1])
|
||||
editVec = Vec3(vWidget2render2d - vMouse2render2d)
|
||||
if base.mouseWatcherNode.getModifierButtons().isDown(
|
||||
KeyboardButton.control()):
|
||||
KeyboardButton.control()):
|
||||
t = taskMgr.add(self.guiScaleTask, 'guiEditTask')
|
||||
t.refPos = vWidget2render2d
|
||||
t.editVecLen = editVec.length()
|
||||
@@ -911,7 +913,6 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
|
||||
self.bounds[2] - bw[1],
|
||||
self.bounds[3] + bw[1])
|
||||
|
||||
|
||||
def getBounds(self, state = 0):
|
||||
self.stateNodePath[state].calcTightBounds(self.ll, self.ur)
|
||||
# Scale bounds to give a pad around graphics
|
||||
|
||||
@@ -9,11 +9,13 @@ __all__ = ['DirectLabel']
|
||||
from panda3d.core import PGItem
|
||||
from .DirectFrame import DirectFrame
|
||||
|
||||
|
||||
class DirectLabel(DirectFrame):
|
||||
"""
|
||||
DirectLabel(parent) - Create a DirectGuiWidget which has multiple
|
||||
states. User explicitly chooses a state to display
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectFrame
|
||||
# A Direct Frame can have:
|
||||
@@ -32,7 +34,7 @@ class DirectLabel(DirectFrame):
|
||||
('numStates', 1, None),
|
||||
('state', self.inactiveInitState, None),
|
||||
('activeState', 0, self.setActiveState),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ class DirectOptionMenu(DirectButton):
|
||||
To cancel the popup menu click anywhere on the screen outside of the
|
||||
popup menu. No command is executed in this case.
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectButton
|
||||
optiondefs = (
|
||||
@@ -42,7 +43,7 @@ class DirectOptionMenu(DirectButton):
|
||||
('text_align', TextNode.ALeft, None),
|
||||
# Remove press effect because it looks a bit funny
|
||||
('pressEffect', 0, DGG.INITOPT),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
# Initialize superclasses
|
||||
|
||||
@@ -14,12 +14,14 @@ from . import DirectGuiGlobals as DGG
|
||||
from .DirectButton import DirectButton
|
||||
from .DirectLabel import DirectLabel
|
||||
|
||||
|
||||
class DirectRadioButton(DirectButton):
|
||||
"""
|
||||
DirectRadioButton(parent) - Create a DirectGuiWidget which responds
|
||||
to mouse clicks by setting given value to given variable and
|
||||
execute a callback function (passing that state through) if defined
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Inherits from DirectButton
|
||||
# A Direct Frame can have:
|
||||
@@ -54,7 +56,7 @@ class DirectRadioButton(DirectButton):
|
||||
('boxImageScale', 1.0, None),
|
||||
('boxImageColor', VBase4(1, 1, 1, 1), None),
|
||||
('boxRelief', None, None),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
# Initialize superclasses
|
||||
@@ -194,7 +196,6 @@ class DirectRadioButton(DirectButton):
|
||||
|
||||
self.indicator.setPos(newpos[0], newpos[1], newpos[2])
|
||||
|
||||
|
||||
def commandFunc(self, event):
|
||||
if len(self['value']) == len(self['variable']) != 0:
|
||||
for i in range(len(self['value'])):
|
||||
|
||||
@@ -17,6 +17,7 @@ class DirectScrollBar(DirectFrame):
|
||||
DirectScrollBar -- a widget which represents a scroll bar the user can
|
||||
use for paging through a large document or panel.
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
optiondefs = (
|
||||
# Define type of DirectGuiWidget
|
||||
@@ -35,18 +36,18 @@ class DirectScrollBar(DirectFrame):
|
||||
# Function to be called repeatedly as the bar is scrolled
|
||||
('command', None, None),
|
||||
('extraArgs', [], None),
|
||||
)
|
||||
)
|
||||
|
||||
if kw.get('orientation') in (DGG.VERTICAL, DGG.VERTICAL_INVERTED):
|
||||
# These are the default options for a vertical layout.
|
||||
optiondefs += (
|
||||
('frameSize', (-0.04, 0.04, -0.5, 0.5), None),
|
||||
)
|
||||
)
|
||||
else:
|
||||
# These are the default options for a horizontal layout.
|
||||
optiondefs += (
|
||||
('frameSize', (-0.5, 0.5, -0.04, 0.04), None),
|
||||
)
|
||||
)
|
||||
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -24,6 +24,7 @@ class DirectScrolledFrame(DirectFrame):
|
||||
0 and explicitly position and hide or show the scroll bars
|
||||
yourself.
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
optiondefs = (
|
||||
# Define type of DirectGuiWidget
|
||||
@@ -35,7 +36,7 @@ class DirectScrolledFrame(DirectFrame):
|
||||
('autoHideScrollBars', 1, self.setAutoHideScrollBars),
|
||||
('scrollBarWidth', 0.08, self.setScrollBarWidth),
|
||||
('borderWidth', (0.01, 0.01), self.setBorderWidth),
|
||||
)
|
||||
)
|
||||
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -37,7 +37,7 @@ class DirectScrolledListItem(DirectButton):
|
||||
optiondefs = (
|
||||
('parent', self._parent, None),
|
||||
('command', self.select, None),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
DirectButton.__init__(self)
|
||||
@@ -91,7 +91,7 @@ class DirectScrolledList(DirectFrame):
|
||||
('forceHeight', None, self.setForceHeight),
|
||||
('incButtonCallback', None, self.setIncButtonCallback),
|
||||
('decButtonCallback', None, self.setDecButtonCallback),
|
||||
)
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -198,7 +198,7 @@ class DirectScrolledList(DirectFrame):
|
||||
#print "scrollTo[", index,"] called, len(self[items])=", len(self["items"])," self[numItemsVisible]=", self["numItemsVisible"]
|
||||
try:
|
||||
self["numItemsVisible"]
|
||||
except:
|
||||
except Exception:
|
||||
# RAU hack to kill 27633
|
||||
self.notify.info('crash 27633 fixed!')
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@ class DirectSlider(DirectFrame):
|
||||
DirectSlider -- a widget which represents a slider that the
|
||||
user can pull left and right to represent a continuous value.
|
||||
"""
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
optiondefs = (
|
||||
# Define type of DirectGuiWidget
|
||||
@@ -34,20 +35,20 @@ class DirectSlider(DirectFrame):
|
||||
# Function to be called repeatedly as slider is moved
|
||||
('command', None, None),
|
||||
('extraArgs', [], None),
|
||||
)
|
||||
)
|
||||
|
||||
if kw.get('orientation') in (DGG.VERTICAL, DGG.VERTICAL_INVERTED):
|
||||
# These are the default options for a vertical layout.
|
||||
optiondefs += (
|
||||
('frameSize', (-0.08, 0.08, -1, 1), None),
|
||||
('frameVisibleScale', (0.25, 1), None),
|
||||
)
|
||||
)
|
||||
else:
|
||||
# These are the default options for a horizontal layout.
|
||||
optiondefs += (
|
||||
('frameSize', (-1, 1, -0.08, 0.08), None),
|
||||
('frameVisibleScale', (1, 0.25), None),
|
||||
)
|
||||
)
|
||||
|
||||
# Merge keyword options with default options
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
@@ -33,12 +33,12 @@ class DirectWaitBar(DirectFrame):
|
||||
('barTexture', None, self.setBarTexture),
|
||||
('barRelief', DGG.FLAT, self.setBarRelief),
|
||||
('sortOrder', DGG.NO_FADE_SORT_INDEX, None),
|
||||
)
|
||||
)
|
||||
if 'text' in kw:
|
||||
textoptiondefs = (
|
||||
('text_pos', (0, -0.025), None),
|
||||
('text_scale', 0.1, None)
|
||||
)
|
||||
)
|
||||
else:
|
||||
textoptiondefs = ()
|
||||
# Merge keyword options with default options
|
||||
|
||||
@@ -20,6 +20,7 @@ ScreenPrompt = 3
|
||||
NameConfirm = 4
|
||||
BlackOnWhite = 5
|
||||
|
||||
|
||||
class OnscreenText(NodePath):
|
||||
|
||||
def __init__(self, text = '',
|
||||
@@ -465,7 +466,7 @@ class OnscreenText(NodePath):
|
||||
Mat4.scaleMat(Vec3.rfu(self.__scale[0], 1, self.__scale[1])) *
|
||||
Mat4.rotateMat(self.__roll, Vec3.back()) *
|
||||
Mat4.translateMat(Point3.rfu(self.__pos[0], 0, self.__pos[1]))
|
||||
)
|
||||
)
|
||||
self.textNode.setTransform(mat)
|
||||
|
||||
def setWordwrap(self, wordwrap):
|
||||
|
||||
@@ -15,8 +15,8 @@ from .IndirectInterval import *
|
||||
from .MopathInterval import *
|
||||
try:
|
||||
import panda3d.physics
|
||||
##Some people may have the particle system compiled out
|
||||
if hasattr( panda3d.physics, 'ParticleSystem' ):
|
||||
# Some people may have the particle system compiled out
|
||||
if hasattr(panda3d.physics, 'ParticleSystem'):
|
||||
from .ParticleInterval import *
|
||||
if __debug__:
|
||||
from .TestInterval import *
|
||||
|
||||
@@ -10,7 +10,7 @@ __all__ = [
|
||||
'LerpColorInterval', 'LerpColorScaleInterval',
|
||||
'LerpTexOffsetInterval', 'LerpTexRotateInterval', 'LerpTexScaleInterval',
|
||||
'LerpFunctionInterval', 'LerpFunc','LerpFunctionNoStateInterval','LerpFuncNS'
|
||||
]
|
||||
]
|
||||
|
||||
from panda3d.core import LOrientationf, NodePath
|
||||
from panda3d.direct import CInterval, CLerpNodePathInterval
|
||||
@@ -25,6 +25,7 @@ from . import LerpBlendHelpers
|
||||
# performance.
|
||||
#
|
||||
|
||||
|
||||
class LerpNodePathInterval(CLerpNodePathInterval):
|
||||
# This is the base class for all of the lerps, defined below, that
|
||||
# affect a property on a NodePath, like pos or hpr.
|
||||
@@ -99,6 +100,7 @@ class LerpNodePathInterval(CLerpNodePathInterval):
|
||||
##
|
||||
#####################################################################
|
||||
|
||||
|
||||
class LerpPosInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, startPos = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -157,6 +159,7 @@ class LerpHprInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartQuat, self.startQuat)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpQuatInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, quat = None,
|
||||
startHpr = None, startQuat = None,
|
||||
@@ -195,6 +198,7 @@ class LerpQuatInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartQuat, self.startQuat)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, scale, startScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -220,6 +224,7 @@ class LerpScaleInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartScale, self.startScale)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpShearInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, shear, startShear = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -245,6 +250,7 @@ class LerpShearInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartShear, self.startShear)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosHprInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, hpr,
|
||||
startPos = None, startHpr = None, startQuat = None,
|
||||
@@ -282,6 +288,7 @@ class LerpPosHprInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartQuat, self.startQuat)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosQuatInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, quat = None,
|
||||
startPos = None, startHpr = None, startQuat = None,
|
||||
@@ -327,6 +334,7 @@ class LerpPosQuatInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartQuat, self.startQuat)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpHprScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, hpr, scale,
|
||||
startHpr = None, startQuat = None, startScale = None,
|
||||
@@ -365,6 +373,7 @@ class LerpHprScaleInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartScale, self.startScale)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpQuatScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, quat = None, scale = None,
|
||||
hpr = None,
|
||||
@@ -413,6 +422,7 @@ class LerpQuatScaleInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartScale, self.startScale)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosHprScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, hpr, scale,
|
||||
startPos = None, startHpr = None, startQuat = None,
|
||||
@@ -459,6 +469,7 @@ class LerpPosHprScaleInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartScale, self.startScale)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosQuatScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, quat = None, scale = None,
|
||||
startPos = None, startHpr = None, startQuat = None,
|
||||
@@ -515,6 +526,7 @@ class LerpPosQuatScaleInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartScale, self.startScale)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosHprScaleShearInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, hpr, scale, shear,
|
||||
startPos = None, startHpr = None, startQuat = None,
|
||||
@@ -569,6 +581,7 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartShear, self.startShear)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpPosQuatScaleShearInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, pos, quat = None, scale = None,
|
||||
shear = None,
|
||||
@@ -635,6 +648,7 @@ class LerpPosQuatScaleShearInterval(LerpNodePathInterval):
|
||||
self.setupParam(self.setStartShear, self.startShear)
|
||||
LerpNodePathInterval.privDoEvent(self, t, event)
|
||||
|
||||
|
||||
class LerpColorInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, color, startColor = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -647,6 +661,7 @@ class LerpColorInterval(LerpNodePathInterval):
|
||||
if override is not None:
|
||||
self.setOverride(override)
|
||||
|
||||
|
||||
class LerpColorScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, colorScale, startColorScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -659,6 +674,7 @@ class LerpColorScaleInterval(LerpNodePathInterval):
|
||||
if override is not None:
|
||||
self.setOverride(override)
|
||||
|
||||
|
||||
class LerpTexOffsetInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, texOffset, startTexOffset = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -674,6 +690,7 @@ class LerpTexOffsetInterval(LerpNodePathInterval):
|
||||
if override is not None:
|
||||
self.setOverride(override)
|
||||
|
||||
|
||||
class LerpTexRotateInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, texRotate, startTexRotate = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -689,6 +706,7 @@ class LerpTexRotateInterval(LerpNodePathInterval):
|
||||
if override is not None:
|
||||
self.setOverride(override)
|
||||
|
||||
|
||||
class LerpTexScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, nodePath, duration, texScale, startTexScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
@@ -705,8 +723,6 @@ class LerpTexScaleInterval(LerpNodePathInterval):
|
||||
self.setOverride(override)
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# The remaining intervals defined in this module are the old-school
|
||||
# Python-based intervals.
|
||||
@@ -733,6 +749,7 @@ class LerpFunctionNoStateInterval(Interval.Interval):
|
||||
# create LerpFunctionInterval DirectNotify category
|
||||
notify = directNotify.newCategory('LerpFunctionNoStateInterval')
|
||||
# Class methods
|
||||
|
||||
def __init__(self, function, duration = 0.0, fromData = 0, toData = 1,
|
||||
blendType = 'noBlend', extraArgs = [], name = None):
|
||||
"""__init__(function, duration, fromData, toData, name)
|
||||
@@ -758,9 +775,8 @@ class LerpFunctionNoStateInterval(Interval.Interval):
|
||||
# Initialize superclass
|
||||
Interval.Interval.__init__(self, name, duration)
|
||||
|
||||
#def privDoEvent(self,t,event):
|
||||
|
||||
#print "doing event",t,event
|
||||
#def privDoEvent(self, t, event):
|
||||
#print("doing event", t, event)
|
||||
#bt = self.blendType(t/self.duration)
|
||||
#data = (self.fromData * (1 - bt)) + (self.toData * bt)
|
||||
## Evaluate function
|
||||
@@ -770,7 +786,7 @@ class LerpFunctionNoStateInterval(Interval.Interval):
|
||||
|
||||
def privStep(self, t):
|
||||
# Evaluate the function
|
||||
#print "doing priv step",t
|
||||
#print("doing priv step", t)
|
||||
if t >= self.duration:
|
||||
# Set to end value
|
||||
if t > self.duration:
|
||||
@@ -787,12 +803,14 @@ class LerpFunctionNoStateInterval(Interval.Interval):
|
||||
self.function(*[data] + self.extraArgs)
|
||||
|
||||
# Print debug information
|
||||
# assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
|
||||
#assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
|
||||
|
||||
self.state = CInterval.SStarted
|
||||
self.currT = t
|
||||
|
||||
# New interface
|
||||
|
||||
|
||||
class LerpFuncNS(LerpFunctionNoStateInterval):
|
||||
def __init__(self, *args, **kw):
|
||||
LerpFunctionNoStateInterval.__init__(self, *args, **kw)
|
||||
@@ -810,6 +828,7 @@ class LerpFunctionInterval(Interval.Interval):
|
||||
# create LerpFunctionInterval DirectNotify category
|
||||
notify = directNotify.newCategory('LerpFunctionInterval')
|
||||
# Class methods
|
||||
|
||||
def __init__(self, function, duration = 0.0, fromData = 0, toData = 1,
|
||||
blendType = 'noBlend', extraArgs = [], name = None):
|
||||
"""__init__(function, duration, fromData, toData, name)
|
||||
@@ -838,7 +857,7 @@ class LerpFunctionInterval(Interval.Interval):
|
||||
|
||||
def privStep(self, t):
|
||||
# Evaluate the function
|
||||
#print "doing priv step",t
|
||||
#print("doing priv step", t)
|
||||
if t >= self.duration:
|
||||
# Set to end value
|
||||
self.function(*[self.toData] + self.extraArgs)
|
||||
@@ -853,12 +872,14 @@ class LerpFunctionInterval(Interval.Interval):
|
||||
self.function(*[data] + self.extraArgs)
|
||||
|
||||
# Print debug information
|
||||
# assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
|
||||
#assert self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
|
||||
|
||||
self.state = CInterval.SStarted
|
||||
self.currT = t
|
||||
|
||||
# New interface
|
||||
|
||||
|
||||
class LerpFunc(LerpFunctionInterval):
|
||||
def __init__(self, *args, **kw):
|
||||
LerpFunctionInterval.__init__(self, *args, **kw)
|
||||
|
||||
@@ -25,23 +25,23 @@ class AnimMgrBase:
|
||||
|
||||
#normal properties
|
||||
self.lerpFuncs = {
|
||||
'H' : self.lerpFuncH,
|
||||
'P' : self.lerpFuncP,
|
||||
'R' : self.lerpFuncR,
|
||||
'SX' : self.lerpFuncSX,
|
||||
'SY' : self.lerpFuncSY,
|
||||
'SZ' : self.lerpFuncSZ,
|
||||
'CR' : self.lerpFuncCR,
|
||||
'CG' : self.lerpFuncCG,
|
||||
'CB' : self.lerpFuncCB,
|
||||
'CA' : self.lerpFuncCA
|
||||
'H': self.lerpFuncH,
|
||||
'P': self.lerpFuncP,
|
||||
'R': self.lerpFuncR,
|
||||
'SX': self.lerpFuncSX,
|
||||
'SY': self.lerpFuncSY,
|
||||
'SZ': self.lerpFuncSZ,
|
||||
'CR': self.lerpFuncCR,
|
||||
'CG': self.lerpFuncCG,
|
||||
'CB': self.lerpFuncCB,
|
||||
'CA': self.lerpFuncCA
|
||||
}
|
||||
|
||||
#Properties which has animation curves
|
||||
self.curveLerpFuncs = {
|
||||
'X' : [ self.lerpFuncX, self.lerpCurveFuncX ],
|
||||
'Y' : [ self.lerpFuncY, self.lerpCurveFuncY ],
|
||||
'Z' : [ self.lerpFuncZ, self.lerpCurveFuncZ ]
|
||||
'X': [self.lerpFuncX, self.lerpCurveFuncX],
|
||||
'Y': [self.lerpFuncY, self.lerpCurveFuncY],
|
||||
'Z': [self.lerpFuncZ, self.lerpCurveFuncZ]
|
||||
}
|
||||
|
||||
def reset(self):
|
||||
|
||||
@@ -10,6 +10,7 @@ class CurveAnimUI(wx.Dialog):
|
||||
"""
|
||||
This is the Curve Animation Panel implementation.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, editor):
|
||||
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Curve Animation",
|
||||
pos=wx.DefaultPosition, size=(430, 140))
|
||||
@@ -20,19 +21,19 @@ class CurveAnimUI(wx.Dialog):
|
||||
|
||||
self.mainPanel = wx.Panel(self, -1)
|
||||
|
||||
self.chooseNode = wx.StaticText( self.mainPanel, -1, "Choose NodePath:")
|
||||
self.chooseNodeTxt = wx.TextCtrl( self.mainPanel, -1, "")
|
||||
self.chooseNodeButton = wx.Button( self.mainPanel, -1, "Choose..")
|
||||
self.chooseNode = wx.StaticText(self.mainPanel, -1, "Choose NodePath:")
|
||||
self.chooseNodeTxt = wx.TextCtrl(self.mainPanel, -1, "")
|
||||
self.chooseNodeButton = wx.Button(self.mainPanel, -1, "Choose..")
|
||||
|
||||
self.chooseCurve = wx.StaticText( self.mainPanel, -1, "Choose attch Curve:")
|
||||
self.chooseCurveTxt = wx.TextCtrl( self.mainPanel, -1, "")
|
||||
self.chooseCurveButton = wx.Button( self.mainPanel, -1, "Choose..")
|
||||
self.chooseCurve = wx.StaticText(self.mainPanel, -1, "Choose attch Curve:")
|
||||
self.chooseCurveTxt = wx.TextCtrl(self.mainPanel, -1, "")
|
||||
self.chooseCurveButton = wx.Button(self.mainPanel, -1, "Choose..")
|
||||
|
||||
self.duritionTime = wx.StaticText( self.mainPanel, -1, "Durition(Frame):")
|
||||
self.duritionTimeSpin = wx.SpinCtrl( self.mainPanel, -1, "",size = (70,25), min=24, max=10000)
|
||||
self.duritionTime = wx.StaticText(self.mainPanel, -1, "Durition(Frame):")
|
||||
self.duritionTimeSpin = wx.SpinCtrl(self.mainPanel, -1, "", size=(70,25), min=24, max=10000)
|
||||
|
||||
self.createAnimButton = wx.Button( self.mainPanel, -1, "Creat")
|
||||
self.saveAnimButton = wx.Button( self.mainPanel, -1, "Save Animation")
|
||||
self.createAnimButton = wx.Button(self.mainPanel, -1, "Creat")
|
||||
self.saveAnimButton = wx.Button(self.mainPanel, -1, "Save Animation")
|
||||
|
||||
self.SetProperties()
|
||||
self.DoLayout()
|
||||
@@ -46,44 +47,44 @@ class CurveAnimUI(wx.Dialog):
|
||||
|
||||
def SetProperties(self):
|
||||
self.duritionTimeSpin.SetValue(24)
|
||||
self.chooseNodeTxt.SetMinSize((200,21))
|
||||
self.chooseCurveTxt.SetMinSize((200,21))
|
||||
self.chooseNodeTxt.SetMinSize((200, 21))
|
||||
self.chooseCurveTxt.SetMinSize((200, 21))
|
||||
self.saveAnimButton.SetToolTipString("Save the animation to the global animation control")
|
||||
|
||||
def DoLayout(self):
|
||||
dialogSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
mainSizer = wx.FlexGridSizer(4, 3, 0, 0)
|
||||
|
||||
mainSizer.Add(self.chooseNode, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
|
||||
mainSizer.Add(self.chooseNodeTxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseNodeButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseNode, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
|
||||
mainSizer.Add(self.chooseNodeTxt, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseNodeButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
mainSizer.Add(self.chooseCurve, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
|
||||
mainSizer.Add(self.chooseCurveTxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseCurveButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseCurve, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
|
||||
mainSizer.Add(self.chooseCurveTxt, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
mainSizer.Add(self.chooseCurveButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
mainSizer.Add(self.duritionTime, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
|
||||
mainSizer.Add(self.duritionTimeSpin, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.createAnimButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.duritionTime, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)
|
||||
mainSizer.Add(self.duritionTimeSpin, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
mainSizer.Add(self.createAnimButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
mainSizer.Add(self.saveAnimButton, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
|
||||
mainSizer.Add(self.saveAnimButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
self.mainPanel.SetSizerAndFit(mainSizer)
|
||||
|
||||
dialogSizer.Add(self.mainPanel, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
dialogSizer.Add(self.mainPanel, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
|
||||
|
||||
self.SetSizer(dialogSizer)
|
||||
self.Layout()
|
||||
|
||||
def OnChooseNode(self, evt):
|
||||
if base.direct.selected.last is None or base.direct.selected.last.hasTag('Controller') or not base.direct.selected.last.hasTag('OBJRoot'):
|
||||
dlg = wx.MessageDialog(None, 'Please select an object.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select an object.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
else:
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||
if obj[OG.OBJ_DEF].name == '__Curve__':
|
||||
dlg = wx.MessageDialog(None, 'Please select an object, not a curve.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select an object, not a curve.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
else:
|
||||
@@ -92,13 +93,13 @@ class CurveAnimUI(wx.Dialog):
|
||||
|
||||
def OnChooseCurve(self, evt):
|
||||
if base.direct.selected.last is None or base.direct.selected.last.hasTag('Controller') or not base.direct.selected.last.hasTag('OBJRoot'):
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
else:
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||
if obj[OG.OBJ_DEF].name != '__Curve__':
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve, not an object.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve, not an object.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
elif obj[OG.OBJ_DEF].name == '__Curve__':
|
||||
@@ -108,43 +109,45 @@ class CurveAnimUI(wx.Dialog):
|
||||
def OnCreateAnim(self, evt):
|
||||
self.time = self.duritionTimeSpin.GetValue()
|
||||
if self.nodePath is None or self.curve is None:
|
||||
dlg = wx.MessageDialog(None, 'Please select an object and a curve first.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select an object and a curve first.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
else:
|
||||
self.curveSequence = self.editor.animMgr.singleCurveAnimation(self.nodePath, self.curve, self.time)
|
||||
self.curveSequence.start()
|
||||
|
||||
def OnSaveAnim(self,evt):
|
||||
def OnSaveAnim(self, evt):
|
||||
if not self.curveSequence:
|
||||
dlg = wx.MessageDialog(None, 'Please create a animation first.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please create an animation first.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
else:
|
||||
if self.editor.animMgr.curveAnimation == {}:
|
||||
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID])] = (self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID],self.time)
|
||||
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID])] = \
|
||||
(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID], self.time)
|
||||
self.editor.updateStatusReadout('Sucessfully saved to global animation list')
|
||||
return
|
||||
|
||||
hasKey = False
|
||||
for key in self.editor.animMgr.curveAnimation:
|
||||
if key == (self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID]):
|
||||
dlg = wx.MessageDialog(None, 'Already have the animation for this object attach to this curve.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Already have the animation for this object attach to this curve.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
hasKey = True
|
||||
return
|
||||
elif self.nodePath[OG.OBJ_UID] == key[0]:
|
||||
dlg = wx.MessageDialog(None, 'This object is already attached to a curve.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'This object is already attached to a curve.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
hasKey = True
|
||||
return
|
||||
|
||||
if not hasKey and self.editor.animMgr.curveAnimation != {}:
|
||||
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID])] = (self.nodePath[OG.OBJ_UID],self.curve[OG.OBJ_UID],self.time)
|
||||
self.editor.animMgr.curveAnimation[(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID])] = \
|
||||
(self.nodePath[OG.OBJ_UID], self.curve[OG.OBJ_UID], self.time)
|
||||
self.editor.updateStatusReadout('Sucessfully saved to global animation list')
|
||||
|
||||
def OnExit(self,evt):
|
||||
def OnExit(self, evt):
|
||||
self.Destroy()
|
||||
self.editor.ui.curveAnimMenuItem.Check(False)
|
||||
|
||||
@@ -11,6 +11,7 @@ from direct.task import Task
|
||||
|
||||
class CurveEditor(DirectObject):
|
||||
""" CurveEditor will create and edit the curve """
|
||||
|
||||
def __init__(self, editor):
|
||||
self.editor = editor
|
||||
self.i = 0
|
||||
@@ -76,11 +77,11 @@ class CurveEditor(DirectObject):
|
||||
self.i = 0
|
||||
for item in self.curveControl:
|
||||
item[1].hide()
|
||||
if self.editor.preMode == self.editor.BASE_MODE :
|
||||
if self.editor.preMode == self.editor.BASE_MODE:
|
||||
pass
|
||||
if self.editor.preMode == self.editor.CREATE_CURVE_MODE :
|
||||
if self.editor.preMode == self.editor.CREATE_CURVE_MODE:
|
||||
self.updateScene()
|
||||
if self.editor.preMode == self.editor.EDIT_CURVE_MODE :
|
||||
if self.editor.preMode == self.editor.EDIT_CURVE_MODE:
|
||||
self.doneEdit()
|
||||
self.curveControl = []
|
||||
self.curve = []
|
||||
|
||||
@@ -48,5 +48,5 @@ class FileMgr:
|
||||
module = imp.load_module(moduleName, file, pathname, description)
|
||||
self.editor.updateStatusReadout('Sucessfully opened file %s'%fileName)
|
||||
self.editor.fNeedToSave = False
|
||||
except:
|
||||
except Exception:
|
||||
print('failed to load %s'%fileName)
|
||||
|
||||
@@ -11,7 +11,7 @@ property = [
|
||||
"translateX",
|
||||
"translateY",
|
||||
"translateZ"
|
||||
]
|
||||
]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
ZoomIn = PyEmbeddedImage(
|
||||
@@ -79,10 +79,12 @@ TwoTangents = PyEmbeddedImage(
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class GraphEditorWindow(wx.Window):
|
||||
"""
|
||||
This is the main graph editor window.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, windowSize, property, xRange, yRange, curFrame, object):
|
||||
wx.Window.__init__(self, parent, size = windowSize, style = wx.SUNKEN_BORDER)
|
||||
|
||||
@@ -388,7 +390,7 @@ class GraphEditorWindow(wx.Window):
|
||||
dc.DrawLine(list[0][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[0][AG.KEYFRAME][AG.LOCAL_VALUE][1], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][1])
|
||||
return
|
||||
|
||||
if len(list)>=3 :
|
||||
if len(list) >= 3:
|
||||
for i in range(len(list)-1):
|
||||
x1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
|
||||
y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
|
||||
@@ -406,7 +408,6 @@ class GraphEditorWindow(wx.Window):
|
||||
scale1 = (x2 - x1) / t1x
|
||||
y2 = y1 - t1y * scale1
|
||||
|
||||
|
||||
x3 = x4 - (x4 - x1) / 3.0
|
||||
scale2 = (x4 - x3) / t2x
|
||||
y3 = y4 + t2y * scale2
|
||||
@@ -445,12 +446,12 @@ class GraphEditorWindow(wx.Window):
|
||||
pointY = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
|
||||
|
||||
if list[i][AG.KEYFRAME][AG.SELECT] == 0:
|
||||
dc.SetPen(wx.Pen("black",3))
|
||||
dc.SetPen(wx.Pen("black", 3))
|
||||
dc.SetBrush(wx.Brush("black"))
|
||||
dc.DrawCircle(pointX, pointY, 2)
|
||||
|
||||
if list[i][AG.KEYFRAME][AG.SELECT] == 1:
|
||||
dc.SetPen(wx.Pen("cyan",3))
|
||||
dc.SetPen(wx.Pen("cyan", 3))
|
||||
dc.SetBrush(wx.Brush("cyan"))
|
||||
dc.DrawCircle(pointX, pointY, 2)
|
||||
|
||||
@@ -460,64 +461,64 @@ class GraphEditorWindow(wx.Window):
|
||||
X1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
|
||||
Y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
|
||||
if self._OneTangent is True:
|
||||
for j in range(3,5):
|
||||
for j in range(3, 5):
|
||||
X = list[i][j][AG.LOCAL_VALUE][0]
|
||||
Y = list[i][j][AG.LOCAL_VALUE][1]
|
||||
if list[i][j][AG.SELECT] == 1:
|
||||
dc.SetPen(wx.Pen("cyan",3))
|
||||
dc.SetPen(wx.Pen("cyan", 3))
|
||||
dc.SetBrush(wx.Brush("cyan"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("cyan",1))
|
||||
dc.SetPen(wx.Pen("cyan", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
if list[i][j][AG.SELECT] == 0:
|
||||
dc.SetPen(wx.Pen("brown",3))
|
||||
dc.SetPen(wx.Pen("brown", 3))
|
||||
dc.SetBrush(wx.Brush("brown"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("brown",1))
|
||||
dc.SetPen(wx.Pen("brown", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
if self._OneTangent is False:
|
||||
if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
|
||||
X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
|
||||
Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
|
||||
dc.SetPen(wx.Pen("cyan",3))
|
||||
dc.SetPen(wx.Pen("cyan", 3))
|
||||
dc.SetBrush(wx.Brush("cyan"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("cyan",1))
|
||||
dc.SetPen(wx.Pen("cyan", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
if list[i][AG.IN_TANGENT][AG.SELECT] == 0:
|
||||
X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
|
||||
Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
|
||||
dc.SetPen(wx.Pen("navy",3))
|
||||
dc.SetPen(wx.Pen("navy", 3))
|
||||
dc.SetBrush(wx.Brush("navy"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("navy",1))
|
||||
dc.SetPen(wx.Pen("navy", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
|
||||
X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
|
||||
Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
|
||||
dc.SetPen(wx.Pen("cyan",3))
|
||||
dc.SetPen(wx.Pen("cyan", 3))
|
||||
dc.SetBrush(wx.Brush("cyan"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("cyan",1))
|
||||
dc.SetPen(wx.Pen("cyan", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
if list[i][AG.OUT_TANGENT][AG.SELECT] == 0:
|
||||
X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
|
||||
Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
|
||||
dc.SetPen(wx.Pen("brown",3))
|
||||
dc.SetPen(wx.Pen("brown", 3))
|
||||
dc.SetBrush(wx.Brush("brown"))
|
||||
dc.DrawCircle(X, Y, 2)
|
||||
|
||||
dc.SetPen(wx.Pen("brown",1))
|
||||
dc.SetPen(wx.Pen("brown", 1))
|
||||
dc.DrawLine(X1, Y1, X, Y)
|
||||
|
||||
def DrawSelectRec(self, dc):
|
||||
@@ -706,7 +707,7 @@ class GraphEditorWindow(wx.Window):
|
||||
newPointX = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0] + moveX
|
||||
newPointY = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1] + moveY
|
||||
|
||||
newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX , newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
|
||||
newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX, newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
|
||||
|
||||
temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0]
|
||||
temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1]
|
||||
@@ -740,7 +741,7 @@ class GraphEditorWindow(wx.Window):
|
||||
newPointX = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0] + moveX
|
||||
newPointY = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1] + moveY
|
||||
|
||||
newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] , list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
|
||||
newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
|
||||
|
||||
temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0]
|
||||
temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1]
|
||||
@@ -785,6 +786,7 @@ class GraphEditorUI(wx.Dialog):
|
||||
"""
|
||||
This is the graph editor main class implementation.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, editor, object):
|
||||
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Graph Editor",
|
||||
pos=wx.DefaultPosition, size=(735, 535))
|
||||
@@ -805,10 +807,10 @@ class GraphEditorUI(wx.Dialog):
|
||||
bmpOneTangent = OneTangent.GetBitmap()
|
||||
bmpTwoTangents = TwoTangents.GetBitmap()
|
||||
|
||||
self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30,30),style = wx.BU_AUTODRAW)
|
||||
self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30,30),style = wx.BU_AUTODRAW)
|
||||
self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30,30),style = wx.BU_AUTODRAW)
|
||||
self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30,30),style = wx.BU_AUTODRAW)
|
||||
self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30, 30),style = wx.BU_AUTODRAW)
|
||||
self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30, 30),style = wx.BU_AUTODRAW)
|
||||
self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30, 30),style = wx.BU_AUTODRAW)
|
||||
self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30, 30),style = wx.BU_AUTODRAW)
|
||||
|
||||
self.mainPanel2 = wx.Panel(self, -1)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class LayerEditorUI(wx.Panel):
|
||||
self.layersDataDict = dict()
|
||||
self.layersDataDictNextKey = 0
|
||||
self.systemLayerKeys = []
|
||||
self.llist = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.LC_EDIT_LABELS|wx.LC_NO_HEADER)
|
||||
self.llist = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_EDIT_LABELS | wx.LC_NO_HEADER)
|
||||
self.llist.InsertColumn(0, "Layers")
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
@@ -170,7 +170,7 @@ class LayerEditorUI(wx.Panel):
|
||||
def removeObj(self):
|
||||
objNodePath = base.direct.selected.last
|
||||
if objNodePath is None:
|
||||
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(objNodePath)
|
||||
if obj is not None:
|
||||
@@ -179,11 +179,11 @@ class LayerEditorUI(wx.Panel):
|
||||
def addObj(self):
|
||||
index = self.llist.GetFirstSelected()
|
||||
if index == -1:
|
||||
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
|
||||
return
|
||||
objNodePath = base.direct.selected.last
|
||||
if objNodePath is None:
|
||||
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("No object was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
|
||||
return
|
||||
|
||||
# Checking if the object was laready added to the layer
|
||||
@@ -193,7 +193,7 @@ class LayerEditorUI(wx.Panel):
|
||||
layersData = self.layersDataDict[i]
|
||||
for j in range(len(layersData)):
|
||||
if layersData[j] == obj[OG.OBJ_UID]:
|
||||
wx.MessageBox("Selected object already is this layer", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("Selected object already is this layer", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
|
||||
return
|
||||
# Looking for the object in the other layers
|
||||
# If the object is found - delete it.
|
||||
@@ -220,7 +220,7 @@ class LayerEditorUI(wx.Panel):
|
||||
def HideObj(self, hide):
|
||||
index = self.llist.GetFirstSelected()
|
||||
if index == -1:
|
||||
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("No layer was selected.", self.editorTxt, wx.OK | wx.ICON_EXCLAMATION)
|
||||
return
|
||||
|
||||
key = self.llist.GetItemData(index)
|
||||
|
||||
@@ -28,6 +28,7 @@ from .MayaConverter import FROM_BAM_TO_MAYA, MayaConverter
|
||||
|
||||
class LevelEditorBase(DirectObject):
|
||||
""" Base Class for Panda3D LevelEditor """
|
||||
|
||||
def __init__(self):
|
||||
#loadPrcFileData('startup', 'window-type none')
|
||||
self.currentFile = None
|
||||
@@ -86,7 +87,7 @@ class LevelEditorBase(DirectObject):
|
||||
('DIRECT-mouse3', self.handleMouse3),
|
||||
('DIRECT-mouse3Up', self.handleMouse3Up),
|
||||
('DIRECT-toggleWidgetVis', self.toggleWidget),
|
||||
])
|
||||
])
|
||||
|
||||
# Add all the action events
|
||||
for event in self.actionEvents:
|
||||
@@ -143,14 +144,12 @@ class LevelEditorBase(DirectObject):
|
||||
if base.direct.fAlt or modifiers == 4:
|
||||
self.fMoveCamera = True
|
||||
return
|
||||
if self.mode == self.CREATE_CURVE_MODE :
|
||||
if self.mode == self.CREATE_CURVE_MODE:
|
||||
self.curveEditor.createCurve()
|
||||
|
||||
|
||||
def handleMouse1Up(self):
|
||||
self.fMoveCamera = False
|
||||
|
||||
|
||||
def handleMouse2(self, modifiers):
|
||||
if base.direct.fAlt or modifiers == 4:
|
||||
self.fMoveCamera = True
|
||||
|
||||
@@ -21,6 +21,7 @@ from .AnimControlUI import AnimControlUI
|
||||
from .CurveAnimUI import CurveAnimUI
|
||||
from .GraphEditorUI import GraphEditorUI
|
||||
|
||||
|
||||
class PandaTextDropTarget(wx.TextDropTarget):
|
||||
def __init__(self, editor, view):
|
||||
wx.TextDropTarget.__init__(self)
|
||||
@@ -104,6 +105,7 @@ class PandaTextDropTarget(wx.TextDropTarget):
|
||||
iRay.collisionNodePath.removeNode()
|
||||
del iRay
|
||||
|
||||
|
||||
ID_NEW = 101
|
||||
ID_OPEN = 102
|
||||
ID_SAVE = 103
|
||||
@@ -129,32 +131,34 @@ ID_CURVE_ANIM = 603
|
||||
ID_ANIM = 701
|
||||
ID_GRAPH = 702
|
||||
|
||||
|
||||
class LevelEditorUIBase(WxPandaShell):
|
||||
""" Class for Panda3D LevelEditor """
|
||||
|
||||
def __init__(self, editor):
|
||||
self.MENU_TEXTS.update({
|
||||
ID_NEW : ("&New", "LE-NewScene"),
|
||||
ID_OPEN : ("&Open", "LE-OpenScene"),
|
||||
ID_SAVE : ("&Save", "LE-SaveScene"),
|
||||
ID_SAVE_AS : ("Save &As", None),
|
||||
ID_EXPORT_TO_MAYA : ("Export to Maya", None),
|
||||
wx.ID_EXIT : ("&Quit", "LE-Quit"),
|
||||
ID_DUPLICATE : ("&Duplicate", "LE-Duplicate"),
|
||||
ID_MAKE_LIVE : ("Make &Live", "LE-MakeLive"),
|
||||
ID_UNDO : ("&Undo", "LE-Undo"),
|
||||
ID_REDO : ("&Redo", "LE-Redo"),
|
||||
ID_SHOW_GRID : ("&Show Grid", None),
|
||||
ID_GRID_SIZE : ("&Grid Size", None),
|
||||
ID_GRID_SNAP : ("Grid S&nap", None),
|
||||
ID_SHOW_PANDA_OBJECT : ("Show &Panda Objects", None),
|
||||
ID_HOT_KEYS : ("&Hot Keys", None),
|
||||
ID_PARENT_TO_SELECTED : ("&Parent To Selected", None),
|
||||
ID_CREATE_CURVE : ("&Create Curve", None),
|
||||
ID_EDIT_CURVE : ("&Edit Curve", None),
|
||||
ID_CURVE_ANIM : ("&Curve Animation", None),
|
||||
ID_ANIM : ("&Edit Animation", None),
|
||||
ID_GRAPH : ("&Graph Editor", None)
|
||||
})
|
||||
ID_NEW: ("&New", "LE-NewScene"),
|
||||
ID_OPEN: ("&Open", "LE-OpenScene"),
|
||||
ID_SAVE: ("&Save", "LE-SaveScene"),
|
||||
ID_SAVE_AS: ("Save &As", None),
|
||||
ID_EXPORT_TO_MAYA: ("Export to Maya", None),
|
||||
wx.ID_EXIT: ("&Quit", "LE-Quit"),
|
||||
ID_DUPLICATE: ("&Duplicate", "LE-Duplicate"),
|
||||
ID_MAKE_LIVE: ("Make &Live", "LE-MakeLive"),
|
||||
ID_UNDO: ("&Undo", "LE-Undo"),
|
||||
ID_REDO: ("&Redo", "LE-Redo"),
|
||||
ID_SHOW_GRID: ("&Show Grid", None),
|
||||
ID_GRID_SIZE: ("&Grid Size", None),
|
||||
ID_GRID_SNAP: ("Grid S&nap", None),
|
||||
ID_SHOW_PANDA_OBJECT: ("Show &Panda Objects", None),
|
||||
ID_HOT_KEYS: ("&Hot Keys", None),
|
||||
ID_PARENT_TO_SELECTED: ("&Parent To Selected", None),
|
||||
ID_CREATE_CURVE: ("&Create Curve", None),
|
||||
ID_EDIT_CURVE: ("&Edit Curve", None),
|
||||
ID_CURVE_ANIM: ("&Curve Animation", None),
|
||||
ID_ANIM: ("&Edit Animation", None),
|
||||
ID_GRAPH: ("&Graph Editor", None)
|
||||
})
|
||||
|
||||
self.editor = editor
|
||||
WxPandaShell.__init__(self, fStartDirect=True)
|
||||
@@ -245,9 +249,9 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
|
||||
WxPandaShell.createMenu(self)
|
||||
|
||||
def onGraphEditor(self,e):
|
||||
def onGraphEditor(self, e):
|
||||
if base.direct.selected.last is None:
|
||||
dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
self.graphEditorMenuItem.Check(False)
|
||||
@@ -257,7 +261,7 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
self.graphEditorUI.Show()
|
||||
self.graphEditorMenuItem.Check(True)
|
||||
|
||||
def onAnimation(self,e):
|
||||
def onAnimation(self, e):
|
||||
if self.editor.mode != self.editor.ANIM_MODE:
|
||||
self.animUI = AnimControlUI(self, self.editor)
|
||||
self.animUI.Show()
|
||||
@@ -265,12 +269,12 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
if self.editor.mode == self.editor.ANIM_MODE:
|
||||
self.editAnimMenuItem.Check(True)
|
||||
|
||||
def onCurveAnim(self,e):
|
||||
def onCurveAnim(self, e):
|
||||
self.curveAnimUI = CurveAnimUI(self, self.editor)
|
||||
self.curveAnimUI.Show()
|
||||
self.curveAnimMenuItem.Check(True)
|
||||
|
||||
def onCreateCurve(self,e):
|
||||
def onCreateCurve(self, e):
|
||||
"""Function to invoke curve creating, need to check previous mode"""
|
||||
if self.editor.mode == self.editor.CREATE_CURVE_MODE:
|
||||
self.createCurveMenuItem.Check(False)
|
||||
@@ -284,7 +288,7 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
else:
|
||||
self.currentView = self.getCurrentView()
|
||||
if self.currentView is None:
|
||||
dlg = wx.MessageDialog(None, 'Please select a viewport first.Do not support curve creation under four viewports.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a viewport first.Do not support curve creation under four viewports.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
self.createCurveMenuItem.Check(False)
|
||||
@@ -297,7 +301,7 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
base.direct.manipulationControl.disableManipulation()
|
||||
self.editCurveMenuItem.Check(False)
|
||||
|
||||
def onEditCurve(self,e):
|
||||
def onEditCurve(self, e):
|
||||
"""Function to invoke curve editing and translate global information to local information. Need to check previous mode"""
|
||||
if self.editor.mode == self.editor.EDIT_CURVE_MODE:
|
||||
self.editCurveMenuItem.Check(False)
|
||||
@@ -310,11 +314,11 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
self.onEditCurve(None)
|
||||
else:
|
||||
if base.direct.selected.last is None:
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
self.editCurveMenuItem.Check(False)
|
||||
if base.direct.selected.last is not None :
|
||||
if base.direct.selected.last is not None:
|
||||
base.direct.manipulationControl.enableManipulation()
|
||||
self.createCurveMenuItem.Check(False)
|
||||
self.curveObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||
@@ -328,7 +332,7 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
item[1].show()
|
||||
self.editor.curveEditor.curve.append((None, item[1].getPos()))
|
||||
else:
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK )
|
||||
dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
self.editCurveMenuItem.Check(False)
|
||||
@@ -603,6 +607,7 @@ class LevelEditorUIBase(WxPandaShell):
|
||||
else:
|
||||
self.editor.objectMgr.replaceObjectWithTypeName(currObj, targetType)
|
||||
|
||||
|
||||
class GridSizeUI(wx.Dialog):
|
||||
def __init__(self, parent, id, title, gridSize, gridSpacing):
|
||||
wx.Dialog.__init__(self, parent, id, title, size=(250, 240))
|
||||
@@ -640,8 +645,10 @@ class GridSizeUI(wx.Dialog):
|
||||
base.le.ui.bindKeyEvents(True)
|
||||
self.Destroy()
|
||||
|
||||
|
||||
class ViewportMenu(wx.Menu):
|
||||
"""Represents a menu that appears when right-clicking a viewport."""
|
||||
|
||||
def __init__(self):
|
||||
wx.Menu.__init__(self)
|
||||
|
||||
@@ -664,6 +671,7 @@ class ViewportMenu(wx.Menu):
|
||||
parent.AppendMenu(id, name, subMenu)
|
||||
return subMenu
|
||||
|
||||
|
||||
class CurveDegreeUI(wx.Dialog):
|
||||
def __init__(self, parent, id, title):
|
||||
wx.Dialog.__init__(self, parent, id, title, size=(150, 120))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import imp
|
||||
|
||||
|
||||
class LevelLoaderBase:
|
||||
"""
|
||||
Base calss for LevelLoader
|
||||
@@ -7,6 +8,7 @@ class LevelLoaderBase:
|
||||
which you will use to load level editor data in your game.
|
||||
Refer LevelLoader.py for example.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.defaultPath = None # this should be set in your LevelLoader.py
|
||||
self.initLoader()
|
||||
@@ -32,6 +34,6 @@ class LevelLoaderBase:
|
||||
try:
|
||||
module = imp.load_module(fileName, file, pathname, description)
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
print('failed to load %s'%fileName)
|
||||
return None
|
||||
|
||||
@@ -18,7 +18,8 @@ from . import ObjectGlobals as OG
|
||||
# python wrapper around a panda.NodePath object
|
||||
class PythonNodePath(NodePath):
|
||||
def __init__(self,node):
|
||||
NodePath.__init__(self,node)
|
||||
NodePath.__init__(self, node)
|
||||
|
||||
|
||||
class ObjectMgrBase:
|
||||
""" ObjectMgr will create, manage, update objects in the scene """
|
||||
@@ -89,21 +90,21 @@ class ObjectMgrBase:
|
||||
for item in curveInfo:
|
||||
controler = base.render.attachNewNode("controler")
|
||||
controler = base.loader.loadModel('models/misc/smiley')
|
||||
controlerPathname = 'controler%d' % item[0]
|
||||
controlerPathname = f'controler{item[0]}'
|
||||
controler.setName(controlerPathname)
|
||||
controler.setPos(item[1])
|
||||
controler.setColor(0, 0, 0, 1)
|
||||
controler.setScale(0.2)
|
||||
controler.reparentTo(base.render)
|
||||
controler.setTag('OBJRoot','1')
|
||||
controler.setTag('Controller','1')
|
||||
controler.setTag('OBJRoot', '1')
|
||||
controler.setTag('Controller', '1')
|
||||
curve.append((None, item[1]))
|
||||
curveControl.append((item[0], controler))
|
||||
|
||||
self.editor.curveEditor.degree = degree
|
||||
self.editor.curveEditor.ropeUpdate (curve)
|
||||
self.editor.curveEditor.ropeUpdate(curve)
|
||||
#add new curve to the scene
|
||||
curveObjNP = self.addNewCurve(curveControl, degree, uid, parent, fSelectObject, nodePath = self.editor.curveEditor.currentRope)
|
||||
curveObjNP = self.addNewCurve(curveControl, degree, uid, parent, fSelectObject, nodePath=self.editor.curveEditor.currentRope)
|
||||
curveObj = self.findObjectByNodePath(curveObjNP)
|
||||
self.editor.objectMgr.updateObjectPropValue(curveObj, 'Degree', degree, fSelectObject=False, fUndo=False)
|
||||
|
||||
@@ -136,7 +137,7 @@ class ObjectMgrBase:
|
||||
newobj = nodePath
|
||||
|
||||
newobj.reparentTo(parent)
|
||||
newobj.setTag('OBJRoot','1')
|
||||
newobj.setTag('OBJRoot', '1')
|
||||
|
||||
# populate obj data using default values
|
||||
properties = {}
|
||||
@@ -254,7 +255,7 @@ class ObjectMgrBase:
|
||||
return None
|
||||
|
||||
newobj.reparentTo(parent)
|
||||
newobj.setTag('OBJRoot','1')
|
||||
newobj.setTag('OBJRoot', '1')
|
||||
|
||||
# populate obj data using default values
|
||||
properties = {}
|
||||
@@ -276,11 +277,11 @@ class ObjectMgrBase:
|
||||
obj = self.findObjectById(uid)
|
||||
nodePath = obj[OG.OBJ_NP]
|
||||
|
||||
for i in range(0,len(self.Actor)):
|
||||
for i in range(0, len(self.Actor)):
|
||||
if self.Actor[i] == obj:
|
||||
del self.Actor[i]
|
||||
break
|
||||
for i in range(0,len(self.Nodes)):
|
||||
for i in range(0, len(self.Nodes)):
|
||||
if self.Nodes[i][OG.OBJ_UID] == uid:
|
||||
del self.Nodes[i]
|
||||
break
|
||||
@@ -300,11 +301,11 @@ class ObjectMgrBase:
|
||||
def removeObjectByNodePath(self, nodePath):
|
||||
uid = self.npIndex.get(nodePath)
|
||||
if uid:
|
||||
for i in range(0,len(self.Actor)):
|
||||
for i in range(0, len(self.Actor)):
|
||||
if self.Actor[i][OG.OBJ_UID] == uid:
|
||||
del self.Actor[i]
|
||||
break
|
||||
for i in range(0,len(self.Nodes)):
|
||||
for i in range(0, len(self.Nodes)):
|
||||
if self.Nodes[i][OG.OBJ_UID] == uid:
|
||||
del self.Nodes[i]
|
||||
break
|
||||
@@ -520,7 +521,7 @@ class ObjectMgrBase:
|
||||
return
|
||||
self.flatten(newobjModel, model, objDef, uid)
|
||||
newobj = PythonNodePath(newobjModel)
|
||||
newobj.setTag('OBJRoot','1')
|
||||
newobj.setTag('OBJRoot', '1')
|
||||
|
||||
# reparent children
|
||||
objNP.findAllMatches("=OBJRoot").reparentTo(newobj)
|
||||
@@ -921,7 +922,6 @@ class ObjectMgrBase:
|
||||
|
||||
self.findActors(child)
|
||||
|
||||
|
||||
def findNodes(self, parent):
|
||||
for child in parent.getChildren():
|
||||
if child.hasTag('OBJRoot') and not child.hasTag('Controller'):
|
||||
|
||||
@@ -17,6 +17,7 @@ and in the populate function you can define ObjectPalette tree structure.
|
||||
from . import ObjectGlobals as OG
|
||||
from .ObjectPaletteBase import ObjectBase, ObjectPaletteBase
|
||||
|
||||
|
||||
class ObjectProp(ObjectBase):
|
||||
def __init__(self, *args, **kw):
|
||||
ObjectBase.__init__(self, *args, **kw)
|
||||
@@ -84,7 +85,7 @@ class ObjectPalette(ObjectPaletteBase):
|
||||
('.updateSmiley',
|
||||
{'val':OG.ARG_VAL, 'obj':OG.ARG_OBJ}),
|
||||
1, [1, 10]],
|
||||
}),
|
||||
}),
|
||||
'Prop') # This object type will be added under the 'Prop' group.
|
||||
self.add(ObjectDoubleSmileys(name='H Double Smiley',
|
||||
createFunction = ('.createDoubleSmiley', {})),
|
||||
|
||||
@@ -4,14 +4,19 @@ from . import ObjectGlobals as OG
|
||||
|
||||
class ObjectGen:
|
||||
""" Base class for obj definitions """
|
||||
|
||||
def __init__(self, name=''):
|
||||
self.name = name
|
||||
|
||||
|
||||
class ObjectBase(ObjectGen):
|
||||
""" Base class for obj definitions """
|
||||
def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], animNames = [], animDict = {}, properties={},
|
||||
movable = True, actor = False, named=False, updateModelFunction = None, orderedProperties=[], propertiesMask={}):
|
||||
|
||||
def __init__(self, name='', createFunction=None, model=None, models=[],
|
||||
anims=[], animNames=[], animDict={}, properties={},
|
||||
movable=True, actor=False, named=False,
|
||||
updateModelFunction=None, orderedProperties=[],
|
||||
propertiesMask={}):
|
||||
ObjectGen.__init__(self, name)
|
||||
self.createFunction = createFunction
|
||||
self.model = model
|
||||
@@ -33,11 +38,14 @@ class ObjectBase(ObjectGen):
|
||||
class ObjectCurve(ObjectBase):
|
||||
def __init__(self, *args, **kw):
|
||||
ObjectBase.__init__(self, *args, **kw)
|
||||
self.properties['Degree'] =[OG.PROP_UI_COMBO, # UI type
|
||||
OG.PROP_INT, # data type
|
||||
('base.le.objectMgr.updateCurve', {'val':OG.ARG_VAL, 'obj':OG.ARG_OBJ}), # update function
|
||||
3, # default value
|
||||
[2, 3, 4]] # value range
|
||||
self.properties['Degree'] = [
|
||||
OG.PROP_UI_COMBO, # UI type
|
||||
OG.PROP_INT, # data type
|
||||
('base.le.objectMgr.updateCurve', {'val': OG.ARG_VAL, 'obj': OG.ARG_OBJ}), # update function
|
||||
3, # default value
|
||||
[2, 3, 4], # value range
|
||||
]
|
||||
|
||||
|
||||
class ObjectPaletteBase:
|
||||
"""
|
||||
@@ -72,9 +80,9 @@ class ObjectPaletteBase:
|
||||
self.data[item.name] = item
|
||||
self.dataKeys.append(item.name)
|
||||
|
||||
def add(self, item, parentName = None):
|
||||
def add(self, item, parentName=None):
|
||||
if isinstance(item, str):
|
||||
self.insertItem(ObjectGen(name = item), parentName)
|
||||
self.insertItem(ObjectGen(name=item), parentName)
|
||||
else:
|
||||
self.insertItem(item, parentName)
|
||||
|
||||
@@ -91,9 +99,8 @@ class ObjectPaletteBase:
|
||||
if node is not None:
|
||||
deleteItems[key] = node
|
||||
return item
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
def delete(self, name):
|
||||
try:
|
||||
@@ -103,14 +110,13 @@ class ObjectPaletteBase:
|
||||
deleteItems[name] = node
|
||||
for key in list(deleteItems.keys()):
|
||||
item = self.dataStruct.pop(key)
|
||||
except:
|
||||
except Exception:
|
||||
return
|
||||
return
|
||||
|
||||
def findItem(self, name):
|
||||
try:
|
||||
item = self.data[name]
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
return item
|
||||
|
||||
@@ -137,7 +143,7 @@ class ObjectPaletteBase:
|
||||
item = self.data.pop(oldName)
|
||||
item.name = newName
|
||||
self.data[newName] = item
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Key = PyEmbeddedImage(
|
||||
"EMaYtpbOXlu01vf5Hz/wDRuDdIDl5WtQAAAAAElFTkSuQmCC")
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class AnimFileDrop(wx.FileDropTarget):
|
||||
def __init__(self, editor):
|
||||
wx.FileDropTarget.__init__(self)
|
||||
@@ -56,11 +57,13 @@ class AnimFileDrop(wx.FileDropTarget):
|
||||
obj[OG.OBJ_ANIM] = animName
|
||||
self.editor.ui.objectPropertyUI.updateProps(obj)
|
||||
|
||||
|
||||
class ObjectPropUI(wx.Panel):
|
||||
"""
|
||||
Base class for ObjectPropUIs,
|
||||
It consists of label area and ui area.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, label):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.parent = parent
|
||||
@@ -80,24 +83,22 @@ class ObjectPropUI(wx.Panel):
|
||||
|
||||
self.setKeyButton.Bind(wx.EVT_BUTTON, self.onKey)
|
||||
|
||||
def onKey(self,evt):
|
||||
def onKey(self, evt):
|
||||
self.parent = wx.GetTopLevelParent(self)
|
||||
if self.parent.editor.mode == self.parent.editor.ANIM_MODE:
|
||||
obj= self.parent.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||
|
||||
objUID = obj[OG.OBJ_UID]
|
||||
propertyName = self.label.GetLabelText()
|
||||
obj = self.parent.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||
|
||||
value = self.getValue()
|
||||
frame = self.parent.editor.ui.animUI.curFrame
|
||||
|
||||
if (objUID, propertyName) in self.parent.editor.animMgr.keyFramesInfo:
|
||||
for i in range(len(self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)])):
|
||||
if self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)][i][AG.FRAME] == frame:
|
||||
del self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)][i]
|
||||
self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)].append([frame, value, [], []])
|
||||
if property in self.parent.editor.animMgr.keyFramesInfo:
|
||||
for i in range(len(self.parent.editor.animMgr.keyFramesInfo[property])):
|
||||
if self.parent.editor.animMgr.keyFramesInfo[property][i][AG.FRAME] == frame:
|
||||
del self.parent.editor.animMgr.keyFramesInfo[property][i]
|
||||
|
||||
self.parent.editor.animMgr.keyFramesInfo[property].append([frame, value, [], []])
|
||||
#sort keyFrameInfo list by the order of frame number
|
||||
sortKeyList = self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)]
|
||||
sortKeyList = self.parent.editor.animMgr.keyFramesInfo[property]
|
||||
for i in range(0, len(sortKeyList)-1):
|
||||
for j in range(i+1, len(sortKeyList)):
|
||||
if sortKeyList[i][AG.FRAME]>sortKeyList[j][AG.FRAME]:
|
||||
@@ -105,9 +106,9 @@ class ObjectPropUI(wx.Panel):
|
||||
sortKeyList[i] = sortKeyList[j]
|
||||
sortKeyList[j] = temp
|
||||
|
||||
self.parent.editor.animMgr.generateSlope(self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)])
|
||||
self.parent.editor.animMgr.generateSlope(self.parent.editor.animMgr.keyFramesInfo[property])
|
||||
else:
|
||||
self.parent.editor.animMgr.keyFramesInfo[(objUID,propertyName)] = [[frame, value, [], []]]
|
||||
self.parent.editor.animMgr.keyFramesInfo[property] = [[frame, value, [], []]]
|
||||
|
||||
exist = False
|
||||
for keyFrame in self.parent.editor.animMgr.keyFrames:
|
||||
@@ -133,8 +134,10 @@ class ObjectPropUI(wx.Panel):
|
||||
if valFunc:
|
||||
self.ui.Bind(self.eventType, valFunc)
|
||||
|
||||
|
||||
class ObjectPropUIEntry(ObjectPropUI):
|
||||
""" UI for string value properties """
|
||||
|
||||
def __init__(self, parent, label):
|
||||
ObjectPropUI.__init__(self, parent, label)
|
||||
self.ui = wx.TextCtrl(self.uiPane, -1)
|
||||
@@ -144,8 +147,10 @@ class ObjectPropUIEntry(ObjectPropUI):
|
||||
def setValue(self, value):
|
||||
self.ui.SetValue(str(value))
|
||||
|
||||
|
||||
class ObjectPropUISlider(ObjectPropUI):
|
||||
""" UI for float value properties """
|
||||
|
||||
def __init__(self, parent, label, value, minValue, maxValue):
|
||||
ObjectPropUI.__init__(self, parent, label)
|
||||
self.ui = WxSlider(self.uiPane, -1, value, minValue, maxValue,
|
||||
@@ -166,6 +171,7 @@ class ObjectPropUISlider(ObjectPropUI):
|
||||
|
||||
class ObjectPropUISpinner(ObjectPropUI):
|
||||
""" UI for int value properties """
|
||||
|
||||
def __init__(self, parent, label, value, minValue, maxValue):
|
||||
ObjectPropUI.__init__(self, parent, label)
|
||||
self.ui = wx.SpinCtrl(self.uiPane, -1, "", min=minValue, max=maxValue, initial=value)
|
||||
@@ -218,6 +224,7 @@ class ObjectPropUICombo(ObjectPropUI):
|
||||
def setItems(self, valueList):
|
||||
self.ui.SetItems(valueList)
|
||||
|
||||
|
||||
class ObjectPropUITime(wx.Panel):
|
||||
def __init__(self, parent, label, value):
|
||||
wx.Panel.__init__(self, parent)
|
||||
@@ -288,9 +295,11 @@ class ObjectPropUITime(wx.Panel):
|
||||
self.uiHour.Bind(self.eventType, valFunc)
|
||||
self.uiMin.Bind(self.eventType, valFunc)
|
||||
|
||||
|
||||
class ColorPicker(CubeColourDialog):
|
||||
def __init__(self, parent, colourData=None, style=CCD_SHOW_ALPHA, alpha = 255, updateCB=None, exitCB=None):
|
||||
self.updateCB=updateCB
|
||||
def __init__(self, parent, colourData=None, style=CCD_SHOW_ALPHA,
|
||||
alpha=255, updateCB=None, exitCB=None):
|
||||
self.updateCB = updateCB
|
||||
CubeColourDialog.__init__(self, parent, colourData, style)
|
||||
self.okButton.Hide()
|
||||
self.cancelButton.Hide()
|
||||
@@ -306,6 +315,7 @@ class ColorPicker(CubeColourDialog):
|
||||
if self.updateCB:
|
||||
self.updateCB(self._colour.r, self._colour.g, self._colour.b, self._colour.alpha)
|
||||
|
||||
|
||||
class ObjectPropertyUI(ScrolledPanel):
|
||||
def __init__(self, parent, editor):
|
||||
self.editor = editor
|
||||
@@ -329,7 +339,7 @@ class ObjectPropertyUI(ScrolledPanel):
|
||||
self.propPane.Destroy()
|
||||
self.SetSizer(None)
|
||||
self.Layout()
|
||||
self.SetupScrolling(self, scroll_y = True, rate_y = 20)
|
||||
self.SetupScrolling(self, scroll_y=True, rate_y=20)
|
||||
|
||||
def colorPickerExitCB(self, evt=None):
|
||||
self.lastColorPickerPos = self.colorPicker.GetPosition()
|
||||
@@ -414,8 +424,11 @@ class ObjectPropertyUI(ScrolledPanel):
|
||||
self.propSY = ObjectPropUIEntry(self.transformPane, 'SY')
|
||||
self.propSZ = ObjectPropUIEntry(self.transformPane, 'SZ')
|
||||
|
||||
transformProps = [self.propX, self.propY, self.propZ, self.propH, self.propP, self.propR,
|
||||
self.propSX, self.propSY, self.propSZ]
|
||||
transformProps = [
|
||||
self.propX, self.propY, self.propZ,
|
||||
self.propH, self.propP, self.propR,
|
||||
self.propSX, self.propSY, self.propSZ,
|
||||
]
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.AddMany(transformProps)
|
||||
@@ -635,7 +648,6 @@ class ObjectPropertyUI(ScrolledPanel):
|
||||
self.editor.objectMgr.onLeaveObjectPropUI,
|
||||
lambda p0=None, p1=obj, p2=key: self.editor.objectMgr.updateObjectProperty(p0, p1, p2))
|
||||
|
||||
|
||||
self.propsPane.SetSizer(sizer)
|
||||
self.Layout()
|
||||
self.SetupScrolling(self, scroll_y = True, rate_y = 20)
|
||||
|
||||
@@ -9,7 +9,7 @@ class ProtoObjs:
|
||||
def __init__(self, name):
|
||||
self.dirname = os.path.dirname(__file__)
|
||||
self.name = name
|
||||
self.filename = "/%s.py" % (name)
|
||||
self.filename = f"/{name}.py"
|
||||
self.data = {}
|
||||
|
||||
def populate(self):
|
||||
@@ -18,16 +18,16 @@ class ProtoObjs:
|
||||
file, pathname, description = imp.find_module(moduleName, [self.dirname])
|
||||
module = imp.load_module(moduleName, file, pathname, description)
|
||||
self.data = module.protoData
|
||||
except:
|
||||
print("%s doesn't exist"%(self.name))
|
||||
except Exception:
|
||||
print(f"{self.name} doesn't exist")
|
||||
return
|
||||
|
||||
def saveProtoData(self, f):
|
||||
if not f:
|
||||
return
|
||||
|
||||
for key in self.data.keys():
|
||||
f.write("\t'%s':'%s',\n"%(key, self.data[key]))
|
||||
for key, value in self.data.items():
|
||||
f.write(f"\t'{key}':'{value}',\n")
|
||||
|
||||
def saveToFile(self):
|
||||
try:
|
||||
@@ -36,5 +36,5 @@ class ProtoObjs:
|
||||
self.saveProtoData(f)
|
||||
f.write("}\n")
|
||||
f.close()
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -7,6 +7,7 @@ from .ActionMgr import ActionChangeHierarchy, ActionDeleteObjById
|
||||
|
||||
from . import ObjectGlobals as OG
|
||||
|
||||
|
||||
class SceneGraphUIDropTarget(wx.TextDropTarget):
|
||||
def __init__(self, editor):
|
||||
print("in SceneGraphUIDropTarget::init...")
|
||||
@@ -17,6 +18,7 @@ class SceneGraphUIDropTarget(wx.TextDropTarget):
|
||||
print("in SceneGraphUIDropTarget::OnDropText...")
|
||||
self.editor.ui.sceneGraphUI.changeHierarchy(text, x, y)
|
||||
|
||||
|
||||
class SceneGraphUIBase(wx.Panel):
|
||||
def __init__(self, parent, editor):
|
||||
wx.Panel.__init__(self, parent)
|
||||
@@ -121,7 +123,7 @@ class SceneGraphUIBase(wx.Panel):
|
||||
if obj is None:
|
||||
return
|
||||
|
||||
if parentNP is None :
|
||||
if parentNP is None:
|
||||
parentNP = obj[OG.OBJ_NP].getParent()
|
||||
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNP)
|
||||
|
||||
|
||||
@@ -68,5 +68,5 @@ if objects['1252623762.9gjeon']:
|
||||
|
||||
if hasattr(base, 'le'):
|
||||
ui.layerEditorUI.reset()
|
||||
ui.layerEditorUI.addLayerEntry('Layer1', 1 )
|
||||
ui.layerEditorUI.addLayerEntry('Layer1', 1)
|
||||
ui.layerEditorUI.addLayerData(1, '1252538687.73gjeon')
|
||||
|
||||
@@ -229,7 +229,7 @@ class MotionTrail(NodePath, DirectObject):
|
||||
|
||||
index = 0
|
||||
while index < total_motion_trails:
|
||||
motion_trail = MotionTrail.motion_trail_list [index]
|
||||
motion_trail = MotionTrail.motion_trail_list[index]
|
||||
|
||||
if MotionTrail.global_enable:
|
||||
if motion_trail.use_python_version:
|
||||
@@ -577,7 +577,7 @@ class MotionTrail(NodePath, DirectObject):
|
||||
v0 = start_transform.xform(motion_trail_vertex_start.vertex)
|
||||
v2 = end_transform.xform(motion_trail_vertex_start.vertex)
|
||||
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list [vertex_segment_index]
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list[vertex_segment_index]
|
||||
|
||||
nurbs_curve_evaluator.setVertex(segment_index, v0)
|
||||
|
||||
@@ -589,7 +589,7 @@ class MotionTrail(NodePath, DirectObject):
|
||||
v1 = start_transform.xform(motion_trail_vertex_end.vertex)
|
||||
v3 = end_transform.xform(motion_trail_vertex_end.vertex)
|
||||
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list [vertex_segment_index + 1]
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list[vertex_segment_index + 1]
|
||||
|
||||
nurbs_curve_evaluator.setVertex(segment_index, v1)
|
||||
|
||||
@@ -607,7 +607,7 @@ class MotionTrail(NodePath, DirectObject):
|
||||
index = 0
|
||||
nurbs_curve_result_list = []
|
||||
while index < self.total_vertices:
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list [index]
|
||||
nurbs_curve_evaluator = nurbs_curve_evaluator_list[index]
|
||||
nurbs_curve_result = nurbs_curve_evaluator.evaluate()
|
||||
nurbs_curve_result_list = nurbs_curve_result_list + [nurbs_curve_result]
|
||||
|
||||
@@ -665,8 +665,8 @@ class MotionTrail(NodePath, DirectObject):
|
||||
motion_trail_vertex_start = self.vertex_list[vertex_segment_index]
|
||||
motion_trail_vertex_end = self.vertex_list[vertex_segment_index + 1]
|
||||
|
||||
start_nurbs_curve_result = nurbs_curve_result_list [vertex_segment_index]
|
||||
end_nurbs_curve_result = nurbs_curve_result_list [vertex_segment_index + 1]
|
||||
start_nurbs_curve_result = nurbs_curve_result_list[vertex_segment_index]
|
||||
end_nurbs_curve_result = nurbs_curve_result_list[vertex_segment_index + 1]
|
||||
|
||||
start_nurbs_start_t = start_nurbs_curve_result.getStartT()
|
||||
start_nurbs_end_t = start_nurbs_curve_result.getEndT()
|
||||
|
||||
@@ -214,7 +214,7 @@ class ParticleEffect(NodePath):
|
||||
data = vfs.readFile(fn, True)
|
||||
data = data.replace(b'\r', b'')
|
||||
exec(data)
|
||||
except:
|
||||
except Exception:
|
||||
self.notify.warning('loadConfig: failed to load particle file: '+ repr(filename))
|
||||
raise
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ class BufferViewer(DirectObject):
|
||||
if not self.isValidTextureSet(elt):
|
||||
return 0
|
||||
else:
|
||||
return (x=="all") or (isinstance(x, Texture)) or (isinstance(x, GraphicsOutput))
|
||||
return x == "all" or isinstance(x, Texture) or isinstance(x, GraphicsOutput)
|
||||
|
||||
def isEnabled(self):
|
||||
"""Returns true if the buffer viewer is currently enabled."""
|
||||
@@ -237,8 +237,8 @@ class BufferViewer(DirectObject):
|
||||
self.analyzeTextureSet(win, set)
|
||||
elif x == "all":
|
||||
self.analyzeTextureSet(self.engine, set)
|
||||
else: return
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
def makeFrame(self, sizex, sizey):
|
||||
"""Access: private. Each texture card is displayed with
|
||||
@@ -271,14 +271,14 @@ class BufferViewer(DirectObject):
|
||||
triangles = GeomTriangles(Geom.UHStatic)
|
||||
for i in range(2):
|
||||
delta = i*8
|
||||
triangles.addVertices(0+delta, 4+delta, 1+delta)
|
||||
triangles.addVertices(1+delta, 4+delta, 5+delta)
|
||||
triangles.addVertices(1+delta, 5+delta, 2+delta)
|
||||
triangles.addVertices(2+delta, 5+delta, 6+delta)
|
||||
triangles.addVertices(2+delta, 6+delta, 3+delta)
|
||||
triangles.addVertices(3+delta, 6+delta, 7+delta)
|
||||
triangles.addVertices(3+delta, 7+delta, 0+delta)
|
||||
triangles.addVertices(0+delta, 7+delta, 4+delta)
|
||||
triangles.addVertices(0 + delta, 4 + delta, 1 + delta)
|
||||
triangles.addVertices(1 + delta, 4 + delta, 5 + delta)
|
||||
triangles.addVertices(1 + delta, 5 + delta, 2 + delta)
|
||||
triangles.addVertices(2 + delta, 5 + delta, 6 + delta)
|
||||
triangles.addVertices(2 + delta, 6 + delta, 3 + delta)
|
||||
triangles.addVertices(3 + delta, 6 + delta, 7 + delta)
|
||||
triangles.addVertices(3 + delta, 7 + delta, 0 + delta)
|
||||
triangles.addVertices(0 + delta, 7 + delta, 4 + delta)
|
||||
triangles.closePrimitive()
|
||||
|
||||
geom = Geom(vdata)
|
||||
@@ -287,7 +287,6 @@ class BufferViewer(DirectObject):
|
||||
geomnode.addGeom(geom)
|
||||
return NodePath(geomnode)
|
||||
|
||||
|
||||
def maintainReadout(self, task):
|
||||
"""Access: private. Whenever necessary, rebuilds the entire
|
||||
display from scratch. This is only done when the configuration
|
||||
@@ -408,24 +407,24 @@ class BufferViewer(DirectObject):
|
||||
|
||||
bordersize = 4.0
|
||||
|
||||
if (float(self.sizex)==0.0) and (float(self.sizey)==0.0):
|
||||
if float(self.sizex) == 0.0 and float(self.sizey) == 0.0:
|
||||
sizey = int(0.4266666667 * self.win.getYSize())
|
||||
sizex = (sizey * aspectx) // aspecty
|
||||
v_sizey = (self.win.getYSize() - (rows-1) - (rows*2)) // rows
|
||||
v_sizey = (self.win.getYSize() - (rows - 1) - (rows * 2)) // rows
|
||||
v_sizex = (v_sizey * aspectx) // aspecty
|
||||
if (v_sizey < sizey) or (v_sizex < sizex):
|
||||
sizey = v_sizey
|
||||
sizex = v_sizex
|
||||
|
||||
adjustment = 2
|
||||
h_sizex = float (self.win.getXSize() - adjustment) / float (cols)
|
||||
h_sizex = float(self.win.getXSize() - adjustment) / float(cols)
|
||||
|
||||
h_sizex -= bordersize
|
||||
if h_sizex < 1.0:
|
||||
h_sizex = 1.0
|
||||
|
||||
h_sizey = (h_sizex * aspecty) // aspectx
|
||||
if (h_sizey < sizey) or (h_sizex < sizex):
|
||||
if h_sizey < sizey or h_sizex < sizex:
|
||||
sizey = h_sizey
|
||||
sizex = h_sizex
|
||||
else:
|
||||
@@ -466,7 +465,7 @@ class BufferViewer(DirectObject):
|
||||
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
index = c + r*cols
|
||||
index = c + r * cols
|
||||
if index < ncards:
|
||||
index = (index + self.cardindex) % len(cards)
|
||||
|
||||
@@ -474,7 +473,7 @@ class BufferViewer(DirectObject):
|
||||
posy = diry * (1.0 - ((r + 0.5) * (fsizey + fpixely * bordersize))) - (fpixely * diry)
|
||||
placer = NodePath("card-structure")
|
||||
placer.setPos(Point3.rfu(posx, 0, posy))
|
||||
placer.setScale(Vec3.rfu(fsizex*0.5, 1.0, fsizey*0.5))
|
||||
placer.setScale(Vec3.rfu(fsizex * 0.5, 1.0, fsizey * 0.5))
|
||||
placer.setBin(self.cullbin, self.cullsort)
|
||||
placer.reparentTo(self.renderParent)
|
||||
frame.instanceTo(placer)
|
||||
|
||||
@@ -33,6 +33,7 @@ def _createContainerLeak():
|
||||
# use tuples as keys since they can't be weakref'd, and use an instance
|
||||
# since it can't be repr/eval'd
|
||||
# that will force the leak detector to hold a normal 'non-weak' reference
|
||||
|
||||
class LeakKey:
|
||||
pass
|
||||
base.leakContainer[(LeakKey(),)] = {}
|
||||
@@ -47,13 +48,17 @@ def _createContainerLeak():
|
||||
return task.done
|
||||
leakContainer()
|
||||
|
||||
|
||||
def _createTaskLeak():
|
||||
leakTaskName = uniqueName('leakedTask')
|
||||
leakDoLaterName = uniqueName('leakedDoLater')
|
||||
|
||||
def nullTask(task=None):
|
||||
return task.cont
|
||||
|
||||
def nullDoLater(task=None):
|
||||
return task.done
|
||||
|
||||
def leakTask(task=None, leakTaskName=leakTaskName):
|
||||
base = getBase()
|
||||
taskMgr.add(nullTask, uniqueName(leakTaskName))
|
||||
@@ -63,9 +68,11 @@ def _createTaskLeak():
|
||||
return task.done
|
||||
leakTask()
|
||||
|
||||
|
||||
class NoDictKey:
|
||||
pass
|
||||
|
||||
|
||||
class Indirection:
|
||||
"""
|
||||
Represents the indirection that brings you from a container to an element of the container.
|
||||
@@ -75,6 +82,7 @@ class Indirection:
|
||||
TODO: store string components that are duplicates of strings in the actual system so that
|
||||
Python will keep one copy and reduce memory usage
|
||||
"""
|
||||
|
||||
def __init__(self, evalStr=None, dictKey=NoDictKey):
|
||||
# if this is a dictionary lookup, pass dictKey instead of evalStr
|
||||
self.evalStr = evalStr
|
||||
@@ -89,7 +97,7 @@ class Indirection:
|
||||
try:
|
||||
keyEval = eval(keyRepr)
|
||||
useEval = True
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if useEval:
|
||||
# check to make sure the eval succeeded
|
||||
@@ -114,6 +122,7 @@ class Indirection:
|
||||
|
||||
def acquire(self):
|
||||
self._refCount += 1
|
||||
|
||||
def release(self):
|
||||
self._refCount -= 1
|
||||
if self._refCount == 0:
|
||||
@@ -164,6 +173,7 @@ class Indirection:
|
||||
def __repr__(self):
|
||||
return self.getString()
|
||||
|
||||
|
||||
class ObjectRef:
|
||||
"""
|
||||
stores a reference to a container in a way that does not prevent garbage
|
||||
@@ -346,10 +356,12 @@ class ObjectRef:
|
||||
pass
|
||||
return result
|
||||
|
||||
|
||||
class FindContainers(Job):
|
||||
"""
|
||||
Explore the Python graph, looking for objects that support __len__()
|
||||
"""
|
||||
|
||||
def __init__(self, name, leakDetector):
|
||||
Job.__init__(self, name)
|
||||
self._leakDetector = leakDetector
|
||||
@@ -382,7 +394,7 @@ class FindContainers(Job):
|
||||
pass
|
||||
try:
|
||||
base
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
ref = ObjectRef(Indirection(evalStr='base.__dict__'), id(base.__dict__))
|
||||
@@ -391,7 +403,7 @@ class FindContainers(Job):
|
||||
pass
|
||||
try:
|
||||
simbase
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
ref = ObjectRef(Indirection(evalStr='simbase.__dict__'), id(simbase.__dict__))
|
||||
@@ -411,7 +423,7 @@ class FindContainers(Job):
|
||||
# how good of a starting object is this object for traversing the object graph?
|
||||
try:
|
||||
return len(startObj)
|
||||
except:
|
||||
except Exception:
|
||||
return 1
|
||||
|
||||
def _isDeadEnd(self, obj, objName=None):
|
||||
@@ -426,7 +438,7 @@ class FindContainers(Job):
|
||||
return True
|
||||
try:
|
||||
className = obj.__class__.__name__
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
# prevent infinite recursion in built-in containers related to methods
|
||||
@@ -512,9 +524,9 @@ class FindContainers(Job):
|
||||
# make a generator that yields containers a # of times that is
|
||||
# proportional to their length
|
||||
for fw in makeFlywheelGen(
|
||||
list(startRefWorkingList.source.values()),
|
||||
countFunc=lambda x: self.getStartObjAffinity(x),
|
||||
scale=.05):
|
||||
list(startRefWorkingList.source.values()),
|
||||
countFunc=lambda x: self.getStartObjAffinity(x),
|
||||
scale=.05):
|
||||
yield None
|
||||
startRefWorkingList.refGen = fw
|
||||
if curObjRef is None:
|
||||
@@ -529,7 +541,7 @@ class FindContainers(Job):
|
||||
try:
|
||||
for containerRef in self._leakDetector.getContainerByIdGen(startId):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# ref is invalid
|
||||
self.notify.debug('invalid startRef, stored as id %s' % startId)
|
||||
self._leakDetector.removeContainerById(startId)
|
||||
@@ -539,7 +551,7 @@ class FindContainers(Job):
|
||||
try:
|
||||
for curObj in curObjRef.getContainerGen():
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
self.notify.debug('lost current container, ref.getContainerGen() failed')
|
||||
# that container is gone, try again
|
||||
curObjRef = None
|
||||
@@ -642,6 +654,7 @@ class FindContainers(Job):
|
||||
raise
|
||||
yield Job.Done
|
||||
|
||||
|
||||
class CheckContainers(Job):
|
||||
"""
|
||||
Job to check container sizes and find potential leaks; sub-job of ContainerLeakDetector
|
||||
@@ -724,7 +737,7 @@ class CheckContainers(Job):
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(objId):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# TODO
|
||||
self.notify.debug('caught exception in getContainerByIdGen (1)')
|
||||
else:
|
||||
@@ -745,7 +758,7 @@ class CheckContainers(Job):
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(objId):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# TODO
|
||||
self.notify.debug('caught exception in getContainerByIdGen (2)')
|
||||
else:
|
||||
@@ -766,7 +779,7 @@ class CheckContainers(Job):
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(objId):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# TODO
|
||||
self.notify.debug('caught exception in getContainerByIdGen (3)')
|
||||
else:
|
||||
@@ -786,6 +799,7 @@ class CheckContainers(Job):
|
||||
raise
|
||||
yield Job.Done
|
||||
|
||||
|
||||
class FPTObjsOfType(Job):
|
||||
def __init__(self, name, leakDetector, otn, doneCallback=None):
|
||||
Job.__init__(self, name)
|
||||
@@ -818,9 +832,9 @@ class FPTObjsOfType(Job):
|
||||
yield None
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(
|
||||
id, getInstance=getInstance):
|
||||
id, getInstance=getInstance):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if hasattr(container, '__class__'):
|
||||
@@ -830,9 +844,9 @@ class FPTObjsOfType(Job):
|
||||
if self._otn.lower() in cName.lower():
|
||||
try:
|
||||
for ptc in self._leakDetector.getContainerNameByIdGen(
|
||||
id, getInstance=getInstance):
|
||||
id, getInstance=getInstance):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print('GPTC(' + self._otn + '):' + self.getJobName() + ': ' + ptc)
|
||||
@@ -846,6 +860,7 @@ class FPTObjsOfType(Job):
|
||||
if self._doneCallback:
|
||||
self._doneCallback(self)
|
||||
|
||||
|
||||
class FPTObjsNamed(Job):
|
||||
def __init__(self, name, leakDetector, on, doneCallback=None):
|
||||
Job.__init__(self, name)
|
||||
@@ -878,7 +893,7 @@ class FPTObjsNamed(Job):
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(id):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
name = self._leakDetector._id2ref[id].getFinalIndirectionStr()
|
||||
@@ -886,7 +901,7 @@ class FPTObjsNamed(Job):
|
||||
try:
|
||||
for ptc in self._leakDetector.getContainerNameByIdGen(id):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print('GPTCN(' + self._on + '):' + self.getJobName() + ': ' + ptc)
|
||||
@@ -900,11 +915,13 @@ class FPTObjsNamed(Job):
|
||||
if self._doneCallback:
|
||||
self._doneCallback(self)
|
||||
|
||||
|
||||
class PruneObjectRefs(Job):
|
||||
"""
|
||||
Job to destroy any container refs that are no longer valid.
|
||||
Checks validity by asking for each container
|
||||
"""
|
||||
|
||||
def __init__(self, name, leakDetector):
|
||||
Job.__init__(self, name)
|
||||
self._leakDetector = leakDetector
|
||||
@@ -926,7 +943,7 @@ class PruneObjectRefs(Job):
|
||||
try:
|
||||
for container in self._leakDetector.getContainerByIdGen(id):
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# reference is invalid, remove it
|
||||
self._leakDetector.removeContainerById(id)
|
||||
_id2baseStartRef = self._leakDetector._findContainersJob._id2baseStartRef
|
||||
@@ -936,7 +953,7 @@ class PruneObjectRefs(Job):
|
||||
try:
|
||||
for container in _id2baseStartRef[id].getContainerGen():
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# reference is invalid, remove it
|
||||
del _id2baseStartRef[id]
|
||||
_id2discoveredStartRef = self._leakDetector._findContainersJob._id2discoveredStartRef
|
||||
@@ -946,7 +963,7 @@ class PruneObjectRefs(Job):
|
||||
try:
|
||||
for container in _id2discoveredStartRef[id].getContainerGen():
|
||||
yield None
|
||||
except:
|
||||
except Exception:
|
||||
# reference is invalid, remove it
|
||||
del _id2discoveredStartRef[id]
|
||||
except Exception as e:
|
||||
@@ -955,6 +972,7 @@ class PruneObjectRefs(Job):
|
||||
raise
|
||||
yield Job.Done
|
||||
|
||||
|
||||
class ContainerLeakDetector(Job):
|
||||
"""
|
||||
Low-priority Python object-graph walker that looks for leaking containers.
|
||||
@@ -1028,12 +1046,14 @@ class ContainerLeakDetector(Job):
|
||||
@classmethod
|
||||
def addPrivateObj(cls, obj):
|
||||
cls.PrivateIds.add(id(obj))
|
||||
|
||||
@classmethod
|
||||
def removePrivateObj(cls, obj):
|
||||
cls.PrivateIds.remove(id(obj))
|
||||
|
||||
def _getCheckTaskName(self):
|
||||
return 'checkForLeakingContainers-%s' % self._serialNum
|
||||
|
||||
def _getPruneTaskName(self):
|
||||
return 'pruneLeakingContainerRefs-%s' % self._serialNum
|
||||
|
||||
@@ -1043,16 +1063,20 @@ class ContainerLeakDetector(Job):
|
||||
def getContainerByIdGen(self, id, **kwArgs):
|
||||
# return a generator to look up a container
|
||||
return self._id2ref[id].getContainerGen(**kwArgs)
|
||||
|
||||
def getContainerById(self, id):
|
||||
for result in self._id2ref[id].getContainerGen():
|
||||
pass
|
||||
return result
|
||||
|
||||
def getContainerNameByIdGen(self, id, **kwArgs):
|
||||
return self._id2ref[id].getEvalStrGen(**kwArgs)
|
||||
|
||||
def getContainerNameById(self, id):
|
||||
if id in self._id2ref:
|
||||
return repr(self._id2ref[id])
|
||||
return '<unknown container>'
|
||||
|
||||
def removeContainerById(self, id):
|
||||
if id in self._id2ref:
|
||||
self._id2ref[id].destroy()
|
||||
|
||||
@@ -53,22 +53,22 @@ class ContainerReport(Job):
|
||||
id(self._type2id2len),
|
||||
id(self._queue),
|
||||
id(self._instanceDictIds),
|
||||
]))
|
||||
]))
|
||||
# push on a few things that we want to give priority
|
||||
# for the sake of the variable-name printouts
|
||||
try:
|
||||
base
|
||||
except:
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
self._enqueueContainer( base.__dict__,
|
||||
self._enqueueContainer(base.__dict__,
|
||||
'base')
|
||||
try:
|
||||
simbase
|
||||
except:
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
self._enqueueContainer( simbase.__dict__,
|
||||
self._enqueueContainer(simbase.__dict__,
|
||||
'simbase')
|
||||
self._queue.push(__builtins__)
|
||||
self._id2pathStr[id(__builtins__)] = ''
|
||||
@@ -86,7 +86,7 @@ class ContainerReport(Job):
|
||||
try:
|
||||
if parentObj.__class__.__name__ == 'method-wrapper':
|
||||
continue
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(parentObj, (str, bytes)):
|
||||
@@ -142,7 +142,7 @@ class ContainerReport(Job):
|
||||
if not isinstance(parentObj, io.TextIOWrapper):
|
||||
try:
|
||||
itr = iter(parentObj)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
@@ -150,7 +150,7 @@ class ContainerReport(Job):
|
||||
while 1:
|
||||
try:
|
||||
attr = next(itr)
|
||||
except:
|
||||
except Exception:
|
||||
# some custom classes don't do well when iterated
|
||||
attr = None
|
||||
break
|
||||
@@ -168,7 +168,7 @@ class ContainerReport(Job):
|
||||
|
||||
try:
|
||||
childNames = dir(parentObj)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
childName = None
|
||||
@@ -176,7 +176,7 @@ class ContainerReport(Job):
|
||||
for childName in childNames:
|
||||
try:
|
||||
child = getattr(parentObj, childName)
|
||||
except:
|
||||
except Exception:
|
||||
continue
|
||||
if id(child) not in self._visitedIds:
|
||||
self._visitedIds.add(id(child))
|
||||
@@ -206,12 +206,13 @@ class ContainerReport(Job):
|
||||
# if it's a container, put it in the tables
|
||||
try:
|
||||
length = len(obj)
|
||||
except:
|
||||
except Exception:
|
||||
length = None
|
||||
if length is not None and length > 0:
|
||||
self._id2container[objId] = obj
|
||||
self._type2id2len.setdefault(type(obj), {})
|
||||
self._type2id2len[type(obj)][objId] = length
|
||||
|
||||
def _examine(self, obj):
|
||||
# return False if it's an object that can't contain or lead to other objects
|
||||
if type(obj) in deadEndTypes:
|
||||
|
||||
@@ -260,6 +260,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath):
|
||||
self.cTrav.traverse(self)
|
||||
base.eventMgr.doEvents()
|
||||
|
||||
|
||||
class BufferedDistancePhasedNode(DistancePhasedNode):
|
||||
"""
|
||||
This class is similar to DistancePhasedNode except you can also
|
||||
@@ -329,7 +330,7 @@ class BufferedDistancePhasedNode(DistancePhasedNode):
|
||||
|
||||
|
||||
if __debug__ and 0:
|
||||
cSphere = CollisionSphere(0,0,0,0.1)
|
||||
cSphere = CollisionSphere(0, 0, 0, 0.1)
|
||||
cNode = CollisionNode('camCol')
|
||||
cNode.addSolid(cSphere)
|
||||
cNodePath = NodePath(cNode)
|
||||
@@ -344,11 +345,11 @@ if __debug__ and 0:
|
||||
eventHandler.addOutPattern('exit%in')
|
||||
|
||||
# messenger.toggleVerbose()
|
||||
base.cTrav.addCollider(cNodePath,eventHandler)
|
||||
base.cTrav.addCollider(cNodePath, eventHandler)
|
||||
|
||||
p = BufferedDistancePhasedNode('p',{'At':(10,20),'Near':(100,200),'Far':(1000, 1020)},
|
||||
autoCleanup = False,
|
||||
fromCollideNode = cNodePath,
|
||||
p = BufferedDistancePhasedNode('p', {'At': (10, 20), 'Near': (100, 200), 'Far': (1000, 1020)},
|
||||
autoCleanup=False,
|
||||
fromCollideNode=cNodePath,
|
||||
)
|
||||
|
||||
p.reparentTo(render)
|
||||
|
||||
@@ -10,6 +10,7 @@ notify = directNotify.newCategory("ExceptionVarDump")
|
||||
|
||||
reentry = 0
|
||||
|
||||
|
||||
def _varDump__init__(self, *args, **kArgs):
|
||||
global reentry
|
||||
if reentry > 0:
|
||||
@@ -30,8 +31,10 @@ def _varDump__init__(self, *args, **kArgs):
|
||||
self._moved__init__(*args, **kArgs)
|
||||
reentry -= 1
|
||||
|
||||
|
||||
sReentry = 0
|
||||
|
||||
|
||||
def _varDump__print(exc):
|
||||
global sReentry
|
||||
global notify
|
||||
@@ -60,6 +63,7 @@ def _varDump__print(exc):
|
||||
notify.info(exc._savedExcString)
|
||||
sReentry -= 1
|
||||
|
||||
|
||||
oldExcepthook = None
|
||||
# store these values here so that Task.py can always reliably access them
|
||||
# from its main exception handler
|
||||
@@ -68,9 +72,11 @@ wantStackDumpUpload = False
|
||||
variableDumpReasons = []
|
||||
dumpOnExceptionInit = False
|
||||
|
||||
|
||||
class _AttrNotFound:
|
||||
pass
|
||||
|
||||
|
||||
def _excepthookDumpVars(eType, eValue, tb):
|
||||
origTb = tb
|
||||
excStrs = traceback.format_exception(eType, eValue, origTb)
|
||||
@@ -137,7 +143,7 @@ def _excepthookDumpVars(eType, eValue, tb):
|
||||
# prevent infinite recursion on method wrappers (__init__.__init__.__init__...)
|
||||
try:
|
||||
className = attr.__class__.__name__
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if className == 'method-wrapper':
|
||||
@@ -168,16 +174,17 @@ def _excepthookDumpVars(eType, eValue, tb):
|
||||
timeMgr = None
|
||||
try:
|
||||
timeMgr = base.cr.timeManager
|
||||
except:
|
||||
except Exception:
|
||||
try:
|
||||
timeMgr = simbase.air.timeManager
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if timeMgr:
|
||||
timeMgr.setStackDump(s)
|
||||
|
||||
oldExcepthook(eType, eValue, origTb)
|
||||
|
||||
|
||||
def install(log, upload):
|
||||
"""Installs the exception hook."""
|
||||
global oldExcepthook
|
||||
|
||||
@@ -60,7 +60,7 @@ def rebindClass(filename):
|
||||
res = findClass(className)
|
||||
|
||||
if not res:
|
||||
print ('Warning: Finder could not find class')
|
||||
print('Warning: Finder could not find class')
|
||||
# Remove the temp file we made
|
||||
file.close()
|
||||
os.remove(filename)
|
||||
@@ -87,7 +87,7 @@ def rebindClass(filename):
|
||||
file.close()
|
||||
os.remove(filename)
|
||||
|
||||
print (' Finished rebind')
|
||||
print(' Finished rebind')
|
||||
|
||||
|
||||
def copyFuncs(fromClass, toClass):
|
||||
@@ -148,25 +148,28 @@ def copyFuncs(fromClass, toClass):
|
||||
# print "adding new func: ", oldFunc, funcName, newFunc
|
||||
setattr(toClass, funcName, newFunc)
|
||||
|
||||
|
||||
def replaceMessengerFunc(replaceFuncList):
|
||||
try:
|
||||
messenger
|
||||
except:
|
||||
except Exception:
|
||||
return
|
||||
for oldFunc, funcName, newFunc in replaceFuncList:
|
||||
res = messenger.replaceMethod(oldFunc, newFunc)
|
||||
if res:
|
||||
print('replaced %s messenger function(s): %s' % (res, funcName))
|
||||
|
||||
|
||||
def replaceTaskMgrFunc(replaceFuncList):
|
||||
try:
|
||||
taskMgr
|
||||
except:
|
||||
except Exception:
|
||||
return
|
||||
for oldFunc, funcName, newFunc in replaceFuncList:
|
||||
if taskMgr.replaceMethod(oldFunc, newFunc):
|
||||
print('replaced taskMgr function: %s' % funcName)
|
||||
|
||||
|
||||
def replaceStateFunc(replaceFuncList):
|
||||
if not sys.modules.get('base.direct.fsm.State'):
|
||||
return
|
||||
@@ -176,28 +179,31 @@ def replaceStateFunc(replaceFuncList):
|
||||
if res:
|
||||
print('replaced %s FSM transition function(s): %s' % (res, funcName))
|
||||
|
||||
|
||||
def replaceCRFunc(replaceFuncList):
|
||||
try:
|
||||
base.cr
|
||||
except:
|
||||
except Exception:
|
||||
return
|
||||
# masad: Gyedo's fake cr causes a crash in followingreplaceMethod on rebinding, so
|
||||
# I throw in the isFake check. I still think the fake cr should be eliminated.
|
||||
if hasattr(base.cr,'isFake'):
|
||||
if hasattr(base.cr, 'isFake'):
|
||||
return
|
||||
for oldFunc, funcName, newFunc in replaceFuncList:
|
||||
if base.cr.replaceMethod(oldFunc, newFunc):
|
||||
print('replaced DistributedObject function: %s' % funcName)
|
||||
|
||||
|
||||
def replaceAIRFunc(replaceFuncList):
|
||||
try:
|
||||
simbase.air
|
||||
except:
|
||||
except Exception:
|
||||
return
|
||||
for oldFunc, funcName, newFunc in replaceFuncList:
|
||||
if simbase.air.replaceMethod(oldFunc, newFunc):
|
||||
print('replaced DistributedObject function: %s' % funcName)
|
||||
|
||||
|
||||
def replaceIvalFunc(replaceFuncList):
|
||||
# Make sure we have imported IntervalManager and thus created
|
||||
# a global ivalMgr.
|
||||
|
||||
@@ -17,10 +17,12 @@ GarbageCycleCountAnnounceEvent = 'announceGarbageCycleDesc2num'
|
||||
class FakeObject:
|
||||
pass
|
||||
|
||||
|
||||
class FakeDelObject:
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
|
||||
def _createGarbage(num=1):
|
||||
for i in range(num):
|
||||
a = FakeObject()
|
||||
@@ -32,6 +34,7 @@ def _createGarbage(num=1):
|
||||
a.other = b
|
||||
b.other = a
|
||||
|
||||
|
||||
class GarbageReport(Job):
|
||||
"""Detects leaked Python objects (via gc.collect()) and reports on garbage
|
||||
items, garbage-to-garbage references, and garbage cycles.
|
||||
@@ -252,7 +255,7 @@ class GarbageReport(Job):
|
||||
brackets = {
|
||||
tuple: '()',
|
||||
list: '[]',
|
||||
}[type(obj)]
|
||||
}[type(obj)]
|
||||
# get object being referenced by container
|
||||
nextObj = objs[index+1]
|
||||
cycleBySyntax += brackets[0]
|
||||
@@ -544,19 +547,23 @@ class GarbageReport(Job):
|
||||
break
|
||||
yield cycles
|
||||
|
||||
|
||||
class GarbageLogger(GarbageReport):
|
||||
"""If you just want to log the current garbage to the log file, make
|
||||
one of these. It automatically destroys itself after logging"""
|
||||
|
||||
def __init__(self, name, *args, **kArgs):
|
||||
kArgs['log'] = True
|
||||
kArgs['autoDestroy'] = True
|
||||
GarbageReport.__init__(self, name, *args, **kArgs)
|
||||
|
||||
|
||||
class _CFGLGlobals:
|
||||
# for checkForGarbageLeaks
|
||||
LastNumGarbage = 0
|
||||
LastNumCycles = 0
|
||||
|
||||
|
||||
def checkForGarbageLeaks():
|
||||
gc.collect()
|
||||
numGarbage = len(gc.garbage)
|
||||
@@ -577,6 +584,7 @@ def checkForGarbageLeaks():
|
||||
func('%s garbage cycles found, see info above' % _CFGLGlobals.LastNumCycles)
|
||||
return numGarbage
|
||||
|
||||
|
||||
def b_checkForGarbageLeaks(wantReply=False):
|
||||
if not __dev__:
|
||||
return 0
|
||||
@@ -586,7 +594,7 @@ def b_checkForGarbageLeaks(wantReply=False):
|
||||
try:
|
||||
# if this is the client, tell the AI to check for leaks too
|
||||
base.cr.timeManager
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if base.cr.timeManager:
|
||||
|
||||
@@ -122,11 +122,7 @@ class SceneGraphLeakDetector(LeakDetector):
|
||||
LeakDetector.destroy(self)
|
||||
|
||||
def __len__(self):
|
||||
try:
|
||||
# this will be available when the build server finishes
|
||||
return self._render.countNumDescendants()
|
||||
except:
|
||||
return self._render.getNumDescendants()
|
||||
return self._render.countNumDescendants()
|
||||
|
||||
def __repr__(self):
|
||||
return 'SceneGraphLeakDetector(%s)' % self._render
|
||||
@@ -138,15 +134,7 @@ class SceneGraphLeakDetector(LeakDetector):
|
||||
|
||||
class CppMemoryUsage(LeakDetector):
|
||||
def __len__(self):
|
||||
haveMemoryUsage = True
|
||||
try:
|
||||
MemoryUsage
|
||||
except:
|
||||
haveMemoryUsage = False
|
||||
if haveMemoryUsage:
|
||||
return int(MemoryUsage.getCurrentCppSize())
|
||||
else:
|
||||
return 0
|
||||
return MemoryUsage.getCurrentCppSize()
|
||||
|
||||
|
||||
class TaskLeakDetectorBase:
|
||||
|
||||
@@ -480,8 +480,8 @@ class Loader(DirectObject):
|
||||
i += 1
|
||||
return cb
|
||||
|
||||
|
||||
# font loading funcs
|
||||
|
||||
def loadFont(self, modelPath,
|
||||
spaceAdvance = None, lineHeight = None,
|
||||
pointSize = None,
|
||||
@@ -926,7 +926,6 @@ class Loader(DirectObject):
|
||||
return texture
|
||||
|
||||
def unloadTexture(self, texture):
|
||||
|
||||
"""
|
||||
Removes the previously-loaded texture from the cache, so
|
||||
that when the last reference to it is gone, it will be
|
||||
@@ -971,7 +970,6 @@ class Loader(DirectObject):
|
||||
|
||||
def loadSound(self, manager, soundPath, positional = False,
|
||||
callback = None, extraArgs = []):
|
||||
|
||||
"""Loads one or more sound files, specifying the particular
|
||||
AudioManager that should be used to load them. The soundPath
|
||||
may be either a single filename, or a list of filenames. If a
|
||||
@@ -1021,7 +1019,7 @@ class Loader(DirectObject):
|
||||
def unloadSfx(self, sfx):
|
||||
if sfx:
|
||||
if self.base.sfxManagerList:
|
||||
self.base.sfxManagerList[0].uncacheSound (sfx.getName())
|
||||
self.base.sfxManagerList[0].uncacheSound(sfx.getName())
|
||||
|
||||
## def makeNodeNamesUnique(self, nodePath, nodeCount):
|
||||
## if nodeCount == 0:
|
||||
@@ -1033,7 +1031,7 @@ class Loader(DirectObject):
|
||||
## self.makeNodeNamesUnique(nodePath.getChild(i), nodeCount)
|
||||
|
||||
def loadShader(self, shaderPath, okMissing = False):
|
||||
shader = ShaderPool.loadShader (shaderPath)
|
||||
shader = ShaderPool.loadShader(shaderPath)
|
||||
if not shader and not okMissing:
|
||||
message = 'Could not load shader file: %s' % (shaderPath)
|
||||
raise IOError(message)
|
||||
|
||||
@@ -417,7 +417,7 @@ class Messenger:
|
||||
# Release the lock temporarily while we call the method.
|
||||
self.lock.release()
|
||||
try:
|
||||
result = method (*(extraArgs + sentArgs))
|
||||
result = method(*(extraArgs + sentArgs))
|
||||
finally:
|
||||
self.lock.acquire()
|
||||
|
||||
|
||||
@@ -11,12 +11,15 @@ import builtins
|
||||
class MessengerLeakObject(DirectObject):
|
||||
def __init__(self):
|
||||
self.accept('leakEvent', self._handleEvent)
|
||||
|
||||
def _handleEvent(self):
|
||||
pass
|
||||
|
||||
|
||||
def _leakMessengerObject():
|
||||
leakObject = MessengerLeakObject()
|
||||
|
||||
|
||||
class MessengerLeakDetector(Job):
|
||||
# check for objects that are only referenced by the messenger
|
||||
# and would otherwise be garbage collected
|
||||
@@ -37,19 +40,19 @@ class MessengerLeakDetector(Job):
|
||||
builtinIds.add(id(base))
|
||||
builtinIds.add(id(base.cr))
|
||||
builtinIds.add(id(base.cr.doId2do))
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
builtinIds.add(id(simbase))
|
||||
builtinIds.add(id(simbase.air))
|
||||
builtinIds.add(id(simbase.air.doId2do))
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
builtinIds.add(id(uber))
|
||||
builtinIds.add(id(uber.air))
|
||||
builtinIds.add(id(uber.air.doId2do))
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
while True:
|
||||
|
||||
@@ -43,7 +43,7 @@ class ObjectPool:
|
||||
self._type2objs[typ].append(obj)
|
||||
try:
|
||||
self._len2obj[len(obj)] = obj
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
self._count2types = invertDictLossless(type2count)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class OnScreenDebug:
|
||||
color = {
|
||||
"black": Vec4(0, 0, 0, 1),
|
||||
"white": Vec4(1, 1, 1, 1),
|
||||
}
|
||||
}
|
||||
fgColor = color[ConfigVariableString("on-screen-debug-fg-color", "white").value]
|
||||
bgColor = color[ConfigVariableString("on-screen-debug-bg-color", "black").value]
|
||||
fgColor.setW(ConfigVariableDouble("on-screen-debug-fg-alpha", 0.85).value)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ __all__ = ['randHash', 'RandomNumGen']
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from panda3d.core import Mersenne
|
||||
|
||||
|
||||
def randHash(num):
|
||||
""" this returns a random 16-bit integer, given a seed integer.
|
||||
It will always return the same output given the same input.
|
||||
@@ -14,9 +15,9 @@ def randHash(num):
|
||||
rng = RandomNumGen(num)
|
||||
return rng.randint(0, (1<<16) - 1)
|
||||
|
||||
|
||||
class RandomNumGen:
|
||||
notify = \
|
||||
DirectNotifyGlobal.directNotify.newCategory("RandomNumGen")
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("RandomNumGen")
|
||||
|
||||
def __init__(self, seed):
|
||||
"""seed must be an integer or another RandomNumGen"""
|
||||
|
||||
@@ -113,7 +113,7 @@ class ReferrerSearch(Job):
|
||||
(isinstance(ref, dict) and \
|
||||
list(ref.keys()) == list(locals().keys())) or \
|
||||
ref is self.__dict__ or \
|
||||
id(ref) in self.visited) ]
|
||||
id(ref) in self.visited)]
|
||||
|
||||
# Check to see if this object has an unusually large
|
||||
# ref-count. This usually indicates that it is some
|
||||
@@ -162,7 +162,7 @@ class ReferrerSearch(Job):
|
||||
# We found the reference on self
|
||||
ref is self.__dict__ or \
|
||||
# We've already seen this referrer
|
||||
id(ref) in self.visited) ]
|
||||
id(ref) in self.visited)]
|
||||
|
||||
# Check to see if this object has an unusually large
|
||||
# ref-count. This usually indicates that it is some
|
||||
|
||||
@@ -146,6 +146,7 @@ if __debug__:
|
||||
from . import OnScreenDebug
|
||||
import warnings
|
||||
|
||||
|
||||
@atexit.register
|
||||
def exitfunc():
|
||||
if getattr(builtins, 'base', None) is not None:
|
||||
@@ -154,6 +155,8 @@ def exitfunc():
|
||||
# Now ShowBase is a DirectObject. We need this so ShowBase can hang
|
||||
# hooks on messages, particularly on window-event. This doesn't
|
||||
# *seem* to cause anyone any problems.
|
||||
|
||||
|
||||
class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
#: The deprecated `.DConfig` interface for accessing config variables.
|
||||
@@ -610,6 +613,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
def pushCTrav(self, cTrav):
|
||||
self.cTravStack.push(self.cTrav)
|
||||
self.cTrav = cTrav
|
||||
|
||||
def popCTrav(self):
|
||||
self.cTrav = self.cTravStack.pop()
|
||||
|
||||
@@ -829,7 +833,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# Save this lambda here for convenience; we'll use it to call
|
||||
# down to the underlying _doOpenWindow() with all of the above
|
||||
# parameters.
|
||||
func = lambda : self._doOpenWindow(
|
||||
func = lambda: self._doOpenWindow(
|
||||
props = props, fbprops = fbprops, pipe = pipe, gsg = gsg,
|
||||
host = host, type = type, name = name, size = size,
|
||||
aspectRatio = aspectRatio, makeCamera = makeCamera,
|
||||
@@ -1728,7 +1732,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
np = mw.getParent().attachNewNode(mouseRecorder)
|
||||
mw.reparentTo(np)
|
||||
|
||||
|
||||
mw = self.buttonThrowers[0].getParent()
|
||||
|
||||
#: A special ButtonThrower to generate keyboard events and
|
||||
@@ -2861,7 +2864,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
camera = None, size = 128,
|
||||
cameraMask = PandaNode.getAllCameraMask(),
|
||||
sourceLens = None):
|
||||
|
||||
"""
|
||||
Similar to :meth:`screenshot()`, this sets up a temporary cube
|
||||
map Texture which it uses to take a series of six snapshots of
|
||||
@@ -3428,7 +3430,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
(self.appRunner.interactiveConsole and not self.appRunner.initialAppImport):
|
||||
self.taskMgr.run()
|
||||
|
||||
|
||||
# Snake-case aliases, for people who prefer these. We're in the process
|
||||
# of migrating everyone to use the snake-case alternatives.
|
||||
make_default_pipe = makeDefaultPipe
|
||||
|
||||
@@ -81,7 +81,7 @@ class Transitions:
|
||||
image = self.fadeModel,
|
||||
image_scale = (4, 2, 2),
|
||||
state = DGG.NORMAL,
|
||||
)
|
||||
)
|
||||
if not self.fadeModel:
|
||||
# No fade model was given, so we make this the fade model.
|
||||
self.fade["relief"] = DGG.FLAT
|
||||
@@ -255,7 +255,6 @@ class Transitions:
|
||||
self.alphaOn.set(r, g, b, 1)
|
||||
self.alphaOff.set(r, g, b, 0)
|
||||
|
||||
|
||||
##################################################
|
||||
# Iris
|
||||
##################################################
|
||||
@@ -403,7 +402,7 @@ class Transitions:
|
||||
image_pos = (0,0,.1),
|
||||
image_color = (0.3,0.3,0.3,1),
|
||||
sortOrder = 0,
|
||||
)
|
||||
)
|
||||
self.letterboxBottom = DirectFrame(
|
||||
parent = self.letterbox,
|
||||
guiId = 'letterboxBottom',
|
||||
@@ -418,7 +417,7 @@ class Transitions:
|
||||
image_pos = (0,0,.1),
|
||||
image_color = (0.3,0.3,0.3,1),
|
||||
sortOrder = 0,
|
||||
)
|
||||
)
|
||||
|
||||
# masad: always place these at the bottom of render
|
||||
self.letterboxTop.setBin('sorted',0)
|
||||
@@ -472,7 +471,7 @@ class Transitions:
|
||||
# startPos = Vec3(0, 0, 1),
|
||||
blendType=blendType
|
||||
),
|
||||
),
|
||||
),
|
||||
Func(self.__finishLetterbox),
|
||||
name = self.letterboxTaskName,
|
||||
)
|
||||
@@ -508,7 +507,7 @@ class Transitions:
|
||||
# startPos = Vec3(0, 0, 0.8),
|
||||
blendType=blendType
|
||||
),
|
||||
),
|
||||
),
|
||||
Func(self.letterbox.stash),
|
||||
Func(self.__finishLetterbox),
|
||||
Func(messenger.send, 'letterboxOff'),
|
||||
|
||||
@@ -31,11 +31,11 @@ sharedPackages = {}
|
||||
|
||||
vfs = VirtualFileSystem.getGlobalPtr()
|
||||
|
||||
compiledExtensions = [ 'pyc', 'pyo' ]
|
||||
compiledExtensions = ['pyc', 'pyo']
|
||||
if not __debug__:
|
||||
# In optimized mode, we prefer loading .pyo files over .pyc files.
|
||||
# We implement that by reversing the extension names.
|
||||
compiledExtensions = [ 'pyo', 'pyc' ]
|
||||
compiledExtensions = ['pyo', 'pyc']
|
||||
|
||||
|
||||
class VFSImporter:
|
||||
@@ -104,6 +104,7 @@ class VFSImporter:
|
||||
#print >>sys.stderr, "not found."
|
||||
return None
|
||||
|
||||
|
||||
class VFSLoader:
|
||||
""" The second part of VFSImporter, this is created for a
|
||||
particular .py file or directory. """
|
||||
@@ -298,7 +299,6 @@ class VFSLoader:
|
||||
else:
|
||||
raise ValueError("Timestamp wrong on %s" % (vfile))
|
||||
|
||||
|
||||
def _compile(self, filename, source):
|
||||
""" Compiles the Python source code to a code object and
|
||||
attempts to write it to an appropriate .pyc file. May raise
|
||||
@@ -472,6 +472,8 @@ class VFSSharedLoader:
|
||||
|
||||
|
||||
_registered = False
|
||||
|
||||
|
||||
def register():
|
||||
""" Register the VFSImporter on the path_hooks, if it has not
|
||||
already been registered, so that future Python import statements
|
||||
|
||||
@@ -51,7 +51,7 @@ def addCircle(attachNode, vertexCount, radius, color = Vec4(1.0, 1.0, 1.0, 1.0),
|
||||
targetCircleColorWriter.addData4f(centerColor[0], centerColor[1], centerColor[2], centerColor[3])
|
||||
|
||||
for vertex in targetCircleShape:
|
||||
targetCircleVertexWriter.addData3f(0.0 + vertex[0] , 0.0 + vertex[1] , zFloat)
|
||||
targetCircleVertexWriter.addData3f(0.0 + vertex[0], 0.0 + vertex[1], zFloat)
|
||||
targetCircleColorWriter.addData4f(color[0], color[1], color[2], color[3])
|
||||
#targetCircleColorWriter.addData4f(1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
@@ -96,7 +96,6 @@ def addSquare(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer
|
||||
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
|
||||
boxTextureWriter = GeomVertexWriter(boxVertexData, "texcoord")
|
||||
|
||||
|
||||
boxVertexWriter.addData3f(-sX, sY, 0.0)
|
||||
boxNormalWriter.addData3f(0, 0, 1)
|
||||
boxColorWriter.addData4f(color[0], color[1], color[2], color[3])
|
||||
@@ -128,7 +127,6 @@ def addSquare(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer
|
||||
boxGeom = Geom(boxVertexData)
|
||||
boxGeom.addPrimitive(boxTris)
|
||||
|
||||
|
||||
attachNode.addGeom(boxGeom)
|
||||
return boxGeom
|
||||
|
||||
@@ -163,7 +161,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
|
||||
boxNormalWriter = GeomVertexWriter(boxVertexData, "normal")
|
||||
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
|
||||
|
||||
|
||||
#Front
|
||||
|
||||
boxVertexWriter.addData3f(sX, sY, sZ)
|
||||
@@ -254,7 +251,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
|
||||
boxNormalWriter.addData3f(0, 0, 1)
|
||||
boxColorWriter.addData4f(color1[0], color1[1], color1[2], color1[3])
|
||||
|
||||
|
||||
#Left
|
||||
|
||||
boxVertexWriter.addData3f(-sX, sY, -sZ)
|
||||
@@ -273,7 +269,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
|
||||
boxNormalWriter.addData3f(0, 0, 1)
|
||||
boxColorWriter.addData4f(color2[0], color2[1], color2[2], color2[3])
|
||||
|
||||
|
||||
boxTris = GeomTristrips(Geom.UHStatic) # trianglestrip obejcet
|
||||
boxTris.addVertex(0)#(1)
|
||||
boxTris.addVertex(1)#(2)
|
||||
@@ -314,7 +309,6 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
|
||||
boxGeom = Geom(boxVertexData)
|
||||
boxGeom.addPrimitive(boxTris)
|
||||
|
||||
|
||||
attachNode.addGeom(boxGeom)
|
||||
return boxGeom
|
||||
|
||||
@@ -344,7 +338,6 @@ def addArrow(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer =
|
||||
boxNormalWriter = GeomVertexWriter(boxVertexData, "normal")
|
||||
boxColorWriter = GeomVertexWriter(boxVertexData, "color")
|
||||
|
||||
|
||||
boxVertexWriter.addData3f(-sX, sY, 0.0)
|
||||
boxNormalWriter.addData3f(0, 0, 1)
|
||||
boxColorWriter.addData4f(color[0], color[1], color[2], color[3])
|
||||
@@ -386,11 +379,9 @@ def addArrow(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer =
|
||||
boxTris.addVertex(6)
|
||||
boxTris.closePrimitive()
|
||||
|
||||
|
||||
boxGeom = Geom(boxVertexData)
|
||||
boxGeom.addPrimitive(boxTris)
|
||||
|
||||
|
||||
attachNode.addGeom(boxGeom)
|
||||
return boxGeom
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ __all__ = [
|
||||
'open', 'listdir', 'walk', 'join',
|
||||
'isfile', 'isdir', 'exists', 'lexists', 'getmtime', 'getsize',
|
||||
'execfile',
|
||||
]
|
||||
]
|
||||
|
||||
from panda3d import core
|
||||
import os
|
||||
@@ -293,6 +293,7 @@ def listdir(path):
|
||||
files.append(file.getFilename().getBasename())
|
||||
return files
|
||||
|
||||
|
||||
def walk(top, topdown = True, onerror = None, followlinks = True):
|
||||
""" Implements os.walk over vfs.
|
||||
|
||||
@@ -321,30 +322,37 @@ def walk(top, topdown = True, onerror = None, followlinks = True):
|
||||
if not topdown:
|
||||
yield (top, dirnames, filenames)
|
||||
|
||||
|
||||
def isfile(path):
|
||||
return _vfs.isRegularFile(core.Filename.fromOsSpecific(path))
|
||||
|
||||
|
||||
def isdir(path):
|
||||
return _vfs.isDirectory(core.Filename.fromOsSpecific(path))
|
||||
|
||||
|
||||
def exists(path):
|
||||
return _vfs.exists(core.Filename.fromOsSpecific(path))
|
||||
|
||||
|
||||
def lexists(path):
|
||||
return _vfs.exists(core.Filename.fromOsSpecific(path))
|
||||
|
||||
|
||||
def getmtime(path):
|
||||
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
|
||||
if not file:
|
||||
raise os.error
|
||||
return file.getTimestamp()
|
||||
|
||||
|
||||
def getsize(path):
|
||||
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
|
||||
if not file:
|
||||
raise os.error
|
||||
return file.getFileSize()
|
||||
|
||||
|
||||
def execfile(path, globals=None, locals=None):
|
||||
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
|
||||
if not file:
|
||||
|
||||
@@ -14,7 +14,7 @@ __all__ = [
|
||||
'force_yield', 'consider_yield',
|
||||
'forceYield', 'considerYield',
|
||||
'TIMEOUT_MAX'
|
||||
]
|
||||
]
|
||||
|
||||
from panda3d import core
|
||||
import sys
|
||||
@@ -85,17 +85,22 @@ class LockType:
|
||||
def __exit__(self, t, v, tb):
|
||||
self.release()
|
||||
|
||||
|
||||
# Helper to generate new thread names
|
||||
_counter = 0
|
||||
|
||||
|
||||
def _newname(template="Thread-%d"):
|
||||
global _counter
|
||||
_counter = _counter + 1
|
||||
return template % _counter
|
||||
|
||||
|
||||
_threads = {}
|
||||
_nextThreadId = 0
|
||||
_threadsLock = core.Mutex('thread._threadsLock')
|
||||
|
||||
|
||||
def start_new_thread(function, args, kwargs = {}, name = None):
|
||||
def threadFunc(threadId, function = function, args = args, kwargs = kwargs):
|
||||
try:
|
||||
@@ -126,6 +131,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
|
||||
finally:
|
||||
_threadsLock.release()
|
||||
|
||||
|
||||
def _add_thread(thread, wrapper):
|
||||
""" Adds the indicated core.Thread object, with the indicated Python
|
||||
wrapper, to the thread list. Returns the new thread ID. """
|
||||
@@ -143,6 +149,7 @@ def _add_thread(thread, wrapper):
|
||||
finally:
|
||||
_threadsLock.release()
|
||||
|
||||
|
||||
def _get_thread_wrapper(thread, wrapperClass):
|
||||
""" Returns the thread wrapper for the indicated thread. If there
|
||||
is not one, creates an instance of the indicated wrapperClass
|
||||
@@ -180,6 +187,7 @@ def _get_thread_wrapper(thread, wrapperClass):
|
||||
finally:
|
||||
_threadsLock.release()
|
||||
|
||||
|
||||
def _get_thread_locals(thread, i):
|
||||
""" Returns the locals dictionary for the indicated thread. If
|
||||
there is not one, creates an empty dictionary. """
|
||||
@@ -237,15 +245,19 @@ def interrupt_main():
|
||||
# TODO.
|
||||
pass
|
||||
|
||||
|
||||
def exit():
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def allocate_lock():
|
||||
return LockType()
|
||||
|
||||
|
||||
def get_ident():
|
||||
return core.Thread.getCurrentThread().this
|
||||
|
||||
|
||||
def stack_size(size = 0):
|
||||
raise error
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ __all__ = [
|
||||
'enumerate', 'active_count',
|
||||
'settrace', 'setprofile', 'stack_size',
|
||||
'TIMEOUT_MAX',
|
||||
]
|
||||
]
|
||||
|
||||
TIMEOUT_MAX = _thread.TIMEOUT_MAX
|
||||
|
||||
@@ -49,6 +49,7 @@ local = _thread._local
|
||||
_newname = _thread._newname
|
||||
ThreadError = _thread.error
|
||||
|
||||
|
||||
class ThreadBase:
|
||||
""" A base class for both Thread and ExternalThread in this
|
||||
module. """
|
||||
@@ -78,12 +79,14 @@ class ThreadBase:
|
||||
else:
|
||||
self.__dict__[key] = value
|
||||
|
||||
|
||||
# Copy these static methods from Panda's Thread object. These are
|
||||
# useful if you may be running in Panda's SIMPLE_THREADS compilation
|
||||
# mode.
|
||||
ThreadBase.forceYield = core.Thread.forceYield
|
||||
ThreadBase.considerYield = core.Thread.considerYield
|
||||
|
||||
|
||||
class Thread(ThreadBase):
|
||||
""" This class provides a wrapper around Panda's PythonThread
|
||||
object. The wrapper is designed to emulate Python's own
|
||||
@@ -161,6 +164,7 @@ class Thread(ThreadBase):
|
||||
self.__dict__['name'] = name
|
||||
self.__thread.setName(name)
|
||||
|
||||
|
||||
class ExternalThread(ThreadBase):
|
||||
""" Returned for a Thread object that wasn't created by this
|
||||
interface. """
|
||||
@@ -191,6 +195,7 @@ class ExternalThread(ThreadBase):
|
||||
def setDaemon(self, daemon):
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
class MainThread(ExternalThread):
|
||||
""" Returned for the MainThread object. """
|
||||
|
||||
@@ -198,6 +203,7 @@ class MainThread(ExternalThread):
|
||||
ExternalThread.__init__(self, extThread, threadId)
|
||||
self.__dict__['daemon'] = False
|
||||
|
||||
|
||||
class Lock(core.Mutex):
|
||||
""" This class provides a wrapper around Panda's Mutex object.
|
||||
The wrapper is designed to emulate Python's own threading.Lock
|
||||
@@ -254,6 +260,7 @@ class Condition(core.ConditionVar):
|
||||
def __exit__(self, t, v, tb):
|
||||
self.release()
|
||||
|
||||
|
||||
class Semaphore(core.Semaphore):
|
||||
""" This class provides a wrapper around Panda's Semaphore
|
||||
object. The wrapper is designed to emulate Python's own
|
||||
@@ -274,6 +281,7 @@ class Semaphore(core.Semaphore):
|
||||
def __exit__(self, t, v, tb):
|
||||
self.release()
|
||||
|
||||
|
||||
class BoundedSemaphore(Semaphore):
|
||||
""" This class provides a wrapper around Panda's Semaphore
|
||||
object. The wrapper is designed to emulate Python's own
|
||||
@@ -289,6 +297,7 @@ class BoundedSemaphore(Semaphore):
|
||||
|
||||
Semaphore.release(self)
|
||||
|
||||
|
||||
class Event:
|
||||
""" This class is designed to emulate Python's own threading.Event
|
||||
object. """
|
||||
@@ -339,6 +348,7 @@ class Event:
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
|
||||
class Timer(Thread):
|
||||
"""Call a function after a specified number of seconds:
|
||||
|
||||
@@ -365,6 +375,7 @@ class Timer(Thread):
|
||||
self.function(*self.args, **self.kwargs)
|
||||
self.finished.set()
|
||||
|
||||
|
||||
def _create_thread_wrapper(t, threadId):
|
||||
""" Creates a thread wrapper for the indicated external thread. """
|
||||
if isinstance(t, core.MainThread):
|
||||
@@ -374,16 +385,20 @@ def _create_thread_wrapper(t, threadId):
|
||||
|
||||
return pyt
|
||||
|
||||
|
||||
def current_thread():
|
||||
t = core.Thread.getCurrentThread()
|
||||
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
|
||||
|
||||
|
||||
def main_thread():
|
||||
t = core.Thread.getMainThread()
|
||||
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
|
||||
|
||||
|
||||
currentThread = current_thread
|
||||
|
||||
|
||||
def enumerate():
|
||||
tlist = []
|
||||
_thread._threadsLock.acquire()
|
||||
@@ -395,24 +410,33 @@ def enumerate():
|
||||
finally:
|
||||
_thread._threadsLock.release()
|
||||
|
||||
|
||||
def active_count():
|
||||
return len(enumerate())
|
||||
|
||||
|
||||
activeCount = active_count
|
||||
|
||||
_settrace_func = None
|
||||
|
||||
|
||||
def settrace(func):
|
||||
global _settrace_func
|
||||
_settrace_func = func
|
||||
|
||||
|
||||
_setprofile_func = None
|
||||
|
||||
|
||||
def setprofile(func):
|
||||
global _setprofile_func
|
||||
_setprofile_func = func
|
||||
|
||||
|
||||
def stack_size(size = None):
|
||||
raise ThreadError
|
||||
|
||||
|
||||
if __debug__:
|
||||
def _test():
|
||||
from collections import deque
|
||||
@@ -482,7 +506,6 @@ if __debug__:
|
||||
self.queue.put("%s.%d" % (self.getName(), counter))
|
||||
_sleep(random() * 0.00001)
|
||||
|
||||
|
||||
class ConsumerThread(Thread):
|
||||
|
||||
def __init__(self, queue, count):
|
||||
|
||||
+43
-6
@@ -74,10 +74,11 @@ def print_exc_plus():
|
||||
#error we don't want.
|
||||
try:
|
||||
valueStr = str(value)
|
||||
except:
|
||||
except Exception:
|
||||
valueStr = "<ERROR WHILE PRINTING VALUE>"
|
||||
print("\t%20s = %s" % (key, valueStr))
|
||||
|
||||
|
||||
# For historical purposes, we remap the C++-defined enumeration to
|
||||
# these Python names, and define them both at the module level, here,
|
||||
# and at the class level (below). The preferred access is via the
|
||||
@@ -109,21 +110,28 @@ Task.DtoolClassDict['pause'] = staticmethod(pause)
|
||||
gather = Task.gather
|
||||
shield = Task.shield
|
||||
|
||||
|
||||
def sequence(*taskList):
|
||||
seq = AsyncTaskSequence('sequence')
|
||||
for task in taskList:
|
||||
seq.addTask(task)
|
||||
return seq
|
||||
|
||||
|
||||
Task.DtoolClassDict['sequence'] = staticmethod(sequence)
|
||||
|
||||
|
||||
def loop(*taskList):
|
||||
seq = AsyncTaskSequence('loop')
|
||||
for task in taskList:
|
||||
seq.addTask(task)
|
||||
seq.setRepeatCount(-1)
|
||||
return seq
|
||||
|
||||
|
||||
Task.DtoolClassDict['loop'] = staticmethod(loop)
|
||||
|
||||
|
||||
class TaskManager:
|
||||
notify = directNotify.newCategory("TaskManager")
|
||||
|
||||
@@ -157,7 +165,7 @@ class TaskManager:
|
||||
taskId = None,
|
||||
profiled = False,
|
||||
session = None,
|
||||
)
|
||||
)
|
||||
|
||||
def finalInit(self):
|
||||
# This function should be called once during startup, after
|
||||
@@ -317,7 +325,6 @@ class TaskManager:
|
||||
def doMethodLater(self, delayTime, funcOrTask, name, extraArgs = None,
|
||||
sort = None, priority = None, taskChain = None,
|
||||
uponDeath = None, appendTask = False, owner = None):
|
||||
|
||||
"""Adds a task to be performed at some time in the future.
|
||||
This is identical to `add()`, except that the specified
|
||||
delayTime is applied to the Task object first, which means
|
||||
@@ -553,6 +560,7 @@ class TaskManager:
|
||||
try:
|
||||
if len(self._frameProfileQueue) > 0:
|
||||
numFrames, session, callback = self._frameProfileQueue.pop(0)
|
||||
|
||||
def _profileFunc(numFrames=numFrames):
|
||||
self._doProfiledFrames(numFrames)
|
||||
session.setFunc(_profileFunc)
|
||||
@@ -605,7 +613,7 @@ class TaskManager:
|
||||
# a nested try block are not caught by the inner try block's except
|
||||
try:
|
||||
(code, message) = ioError
|
||||
except:
|
||||
except Exception:
|
||||
code = 0
|
||||
message = ioError
|
||||
return code, message
|
||||
@@ -709,7 +717,7 @@ class TaskManager:
|
||||
task = task,
|
||||
profiled = False,
|
||||
session = None,
|
||||
)
|
||||
)
|
||||
|
||||
# Temporarily replace the task's own function with our
|
||||
# _profileTask method.
|
||||
@@ -817,6 +825,7 @@ class TaskManager:
|
||||
|
||||
# run-once task
|
||||
l = []
|
||||
|
||||
def _testDone(task, l=l):
|
||||
l.append(None)
|
||||
return task.done
|
||||
@@ -848,6 +857,7 @@ class TaskManager:
|
||||
|
||||
# continued task
|
||||
l = []
|
||||
|
||||
def _testCont(task, l = l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
@@ -862,6 +872,7 @@ class TaskManager:
|
||||
|
||||
# continue until done task
|
||||
l = []
|
||||
|
||||
def _testContDone(task, l = l):
|
||||
l.append(None)
|
||||
if len(l) >= 2:
|
||||
@@ -891,9 +902,11 @@ class TaskManager:
|
||||
|
||||
# task sort
|
||||
l = []
|
||||
|
||||
def _testPri1(task, l = l):
|
||||
l.append(1)
|
||||
return task.cont
|
||||
|
||||
def _testPri2(task, l = l):
|
||||
l.append(2)
|
||||
return task.cont
|
||||
@@ -913,6 +926,7 @@ class TaskManager:
|
||||
|
||||
# task extraArgs
|
||||
l = []
|
||||
|
||||
def _testExtraArgs(arg1, arg2, l=l):
|
||||
l.extend([arg1, arg2,])
|
||||
return done
|
||||
@@ -925,6 +939,7 @@ class TaskManager:
|
||||
|
||||
# task appendTask
|
||||
l = []
|
||||
|
||||
def _testAppendTask(arg1, arg2, task, l=l):
|
||||
l.extend([arg1, arg2,])
|
||||
return task.done
|
||||
@@ -937,8 +952,10 @@ class TaskManager:
|
||||
|
||||
# task uponDeath
|
||||
l = []
|
||||
|
||||
def _uponDeathFunc(task, l=l):
|
||||
l.append(task.name)
|
||||
|
||||
def _testUponDeath(task):
|
||||
return done
|
||||
tm.add(_testUponDeath, 'testUponDeath', uponDeath=_uponDeathFunc)
|
||||
@@ -953,10 +970,12 @@ class TaskManager:
|
||||
class _TaskOwner:
|
||||
def _addTask(self, task):
|
||||
self.addedTaskName = task.name
|
||||
|
||||
def _clearTask(self, task):
|
||||
self.clearedTaskName = task.name
|
||||
to = _TaskOwner()
|
||||
l = []
|
||||
|
||||
def _testOwner(task):
|
||||
return done
|
||||
tm.add(_testOwner, 'testOwner', owner=to)
|
||||
@@ -968,15 +987,17 @@ class TaskManager:
|
||||
_TaskOwner = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
|
||||
doLaterTests = [0,]
|
||||
|
||||
# doLater
|
||||
l = []
|
||||
|
||||
def _testDoLater1(task, l=l):
|
||||
l.append(1)
|
||||
|
||||
def _testDoLater2(task, l=l):
|
||||
l.append(2)
|
||||
|
||||
def _monitorDoLater(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .03:
|
||||
assert l == [1, 2,]
|
||||
@@ -996,10 +1017,13 @@ class TaskManager:
|
||||
|
||||
# doLater sort
|
||||
l = []
|
||||
|
||||
def _testDoLaterPri1(task, l=l):
|
||||
l.append(1)
|
||||
|
||||
def _testDoLaterPri2(task, l=l):
|
||||
l.append(2)
|
||||
|
||||
def _monitorDoLaterPri(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [1, 2,]
|
||||
@@ -1019,8 +1043,10 @@ class TaskManager:
|
||||
|
||||
# doLater extraArgs
|
||||
l = []
|
||||
|
||||
def _testDoLaterExtraArgs(arg1, l=l):
|
||||
l.append(arg1)
|
||||
|
||||
def _monitorDoLaterExtraArgs(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [3,]
|
||||
@@ -1038,9 +1064,11 @@ class TaskManager:
|
||||
|
||||
# doLater appendTask
|
||||
l = []
|
||||
|
||||
def _testDoLaterAppendTask(arg1, task, l=l):
|
||||
assert task.name == 'testDoLaterAppendTask'
|
||||
l.append(arg1)
|
||||
|
||||
def _monitorDoLaterAppendTask(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [4,]
|
||||
@@ -1059,11 +1087,14 @@ class TaskManager:
|
||||
|
||||
# doLater uponDeath
|
||||
l = []
|
||||
|
||||
def _testUponDeathFunc(task, l=l):
|
||||
assert task.name == 'testDoLaterUponDeath'
|
||||
l.append(10)
|
||||
|
||||
def _testDoLaterUponDeath(arg1, l=l):
|
||||
return done
|
||||
|
||||
def _monitorDoLaterUponDeath(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [10,]
|
||||
@@ -1085,12 +1116,15 @@ class TaskManager:
|
||||
class _DoLaterOwner:
|
||||
def _addTask(self, task):
|
||||
self.addedTaskName = task.name
|
||||
|
||||
def _clearTask(self, task):
|
||||
self.clearedTaskName = task.name
|
||||
doLaterOwner = _DoLaterOwner()
|
||||
l = []
|
||||
|
||||
def _testDoLaterOwner(l=l):
|
||||
pass
|
||||
|
||||
def _monitorDoLaterOwner(task, tm=tm, l=l, doLaterOwner=doLaterOwner,
|
||||
doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
@@ -1223,6 +1257,7 @@ class TaskManager:
|
||||
|
||||
# create Task object and add to mgr
|
||||
l = []
|
||||
|
||||
def _testTaskObj(task, l=l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
@@ -1240,6 +1275,7 @@ class TaskManager:
|
||||
|
||||
# remove Task via task.remove()
|
||||
l = []
|
||||
|
||||
def _testTaskObjRemove(task, l=l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
@@ -1299,6 +1335,7 @@ if __debug__:
|
||||
gc.enable()
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
from direct.task.TaskManagerGlobal import taskMgr
|
||||
|
||||
class TestClass(DirectObject):
|
||||
def doTask(self, task):
|
||||
return task.done
|
||||
|
||||
@@ -19,6 +19,7 @@ import tkinter as tk
|
||||
FRAMES = 0
|
||||
SECONDS = 1
|
||||
|
||||
|
||||
class AnimPanel(AppShell):
|
||||
# Override class variables
|
||||
appname = 'Anim Panel'
|
||||
@@ -38,7 +39,7 @@ class AnimPanel(AppShell):
|
||||
('title', self.appname, None),
|
||||
('actorList', [], None),
|
||||
('Actor_label_width', 12, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# direct session that spawned me, if any, used
|
||||
@@ -55,7 +56,6 @@ class AnimPanel(AppShell):
|
||||
# Initialize the superclass
|
||||
AppShell.__init__(self)
|
||||
|
||||
|
||||
# Execute option callbacks
|
||||
self.initialiseoptions(AnimPanel)
|
||||
# We need to know when AnimPanel is closed
|
||||
@@ -270,7 +270,7 @@ class AnimPanel(AppShell):
|
||||
initialdir = '/i/beta',
|
||||
title = 'Load Animation',
|
||||
parent = self.component('hull')
|
||||
)
|
||||
)
|
||||
if not animFilename or animFilename == 'None':
|
||||
# no file selected, canceled
|
||||
return
|
||||
@@ -291,7 +291,6 @@ class AnimPanel(AppShell):
|
||||
self.clearActorControls()
|
||||
self.createActorControls()
|
||||
|
||||
|
||||
def playActorControls(self):
|
||||
self.stopActorControls()
|
||||
self.lastT = ClockObject.getGlobalClock().getFrameTime()
|
||||
@@ -372,6 +371,7 @@ class AnimPanel(AppShell):
|
||||
self.destroyCallBack = None
|
||||
AppShell.destroy(self)
|
||||
|
||||
|
||||
class ActorControl(Pmw.MegaWidget):
|
||||
def __init__(self, parent = None, **kw):
|
||||
|
||||
@@ -391,7 +391,7 @@ class ActorControl(Pmw.MegaWidget):
|
||||
('active', initActive, None),
|
||||
('sLabel_width', 5, None),
|
||||
('sLabel_font', DEFAULT_FONT, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Initialize the superclass
|
||||
@@ -662,6 +662,7 @@ class ActorControl(Pmw.MegaWidget):
|
||||
self.fOneShot = 1
|
||||
self.goToT((self.currT-(1/self.fps))%self.duration)
|
||||
|
||||
|
||||
"""
|
||||
# EXAMPLE CODE
|
||||
from direct.actor import Actor
|
||||
|
||||
@@ -37,7 +37,7 @@ class DirectSessionPanel(AppShell):
|
||||
INITOPT = Pmw.INITOPT
|
||||
optiondefs = (
|
||||
('title', self.appname, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Call superclass initialization function
|
||||
@@ -82,7 +82,7 @@ class DirectSessionPanel(AppShell):
|
||||
('DIRECT_redoListEmpty', self.redoListEmptyHook),
|
||||
('DIRECT_selectedNodePath', self.selectedNodePathHook),
|
||||
('DIRECT_addLight', self.addLight),
|
||||
]
|
||||
]
|
||||
for event, method in self.actionEvents:
|
||||
self.accept(event, method)
|
||||
|
||||
@@ -476,7 +476,6 @@ class DirectSessionPanel(AppShell):
|
||||
|
||||
lightFrame.pack(expand = 1, fill = tk.BOTH)
|
||||
|
||||
|
||||
def createGridPage(self, gridPage):
|
||||
tk.Label(gridPage, text = 'Grid',
|
||||
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
|
||||
@@ -649,7 +648,7 @@ class DirectSessionPanel(AppShell):
|
||||
else:
|
||||
# Good eval but not a node path, give up
|
||||
nodePath = None
|
||||
except:
|
||||
except Exception:
|
||||
# Bogus eval
|
||||
nodePath = None
|
||||
# Clear bogus entry from listbox
|
||||
@@ -699,7 +698,7 @@ class DirectSessionPanel(AppShell):
|
||||
else:
|
||||
# Good eval but not a node path, give up
|
||||
nodePath = None
|
||||
except:
|
||||
except Exception:
|
||||
# Bogus eval
|
||||
nodePath = None
|
||||
# Clear bogus entry from listbox
|
||||
@@ -740,6 +739,7 @@ class DirectSessionPanel(AppShell):
|
||||
# Background #
|
||||
def setBackgroundColor(self, r, g, b):
|
||||
self.setBackgroundColorVec((r, g, b))
|
||||
|
||||
def setBackgroundColorVec(self, color):
|
||||
base.setBackgroundColor(color[0]/255.0,
|
||||
color[1]/255.0,
|
||||
|
||||
@@ -128,7 +128,7 @@ class FSMInspector(AppShell):
|
||||
optiondefs = (
|
||||
('title', fsm.getName(), None),
|
||||
('gridSize', '0.25i', self._setGridSize),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
self.fsm = fsm
|
||||
@@ -393,6 +393,7 @@ class FSMInspector(AppShell):
|
||||
self.ignore(self.name + '_' + si.getName() + '_entered')
|
||||
self.ignore(self.name + '_' + si.getName() + '_exited')
|
||||
|
||||
|
||||
class StateInspector(Pmw.MegaArchetype):
|
||||
def __init__(self, inspector, state, **kw):
|
||||
|
||||
@@ -412,7 +413,7 @@ class StateInspector(Pmw.MegaArchetype):
|
||||
optiondefs = (
|
||||
('radius', '0.375i', self._setRadius),
|
||||
('gridSize', '0.25i', self._setGridSize),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Initialize the parent class
|
||||
@@ -439,7 +440,6 @@ class StateInspector(Pmw.MegaArchetype):
|
||||
half, half,
|
||||
tags = (self.tag,))
|
||||
|
||||
|
||||
# The Popup State Menu
|
||||
self._popupMenu = tk.Menu(self._canvas, tearoff = 0)
|
||||
self._popupMenu.add_command(label = 'Request transition to ' +
|
||||
|
||||
@@ -19,6 +19,7 @@ import tkinter as tk
|
||||
|
||||
### public API
|
||||
|
||||
|
||||
def inspect(anObject):
|
||||
"""Opens up a window for visually inspecting the details of a given Python
|
||||
object. See :ref:`inspection-utilities`.
|
||||
@@ -30,6 +31,7 @@ def inspect(anObject):
|
||||
|
||||
### private
|
||||
|
||||
|
||||
def inspectorFor(anObject):
|
||||
typeName = type(anObject).__name__.capitalize() + 'Type'
|
||||
if typeName in _InspectorMap:
|
||||
@@ -72,7 +74,8 @@ def initializeInspectorMap():
|
||||
'StringType': 'SequenceInspector',
|
||||
'TupleType': 'SequenceInspector',
|
||||
'TypeType': 'Inspector',
|
||||
'UnboundMethodType': 'FunctionInspector'}
|
||||
'UnboundMethodType': 'FunctionInspector',
|
||||
}
|
||||
|
||||
for each in notFinishedTypes:
|
||||
_InspectorMap[each] = 'Inspector'
|
||||
@@ -119,10 +122,7 @@ class Inspector:
|
||||
object = self.partNumber(partNumber)
|
||||
doc = None
|
||||
if callable(object):
|
||||
try:
|
||||
doc = object.__doc__
|
||||
except:
|
||||
pass
|
||||
doc = getattr(object, '__doc__', None)
|
||||
if doc:
|
||||
return str(object) + '\n' + str(doc)
|
||||
else:
|
||||
@@ -150,10 +150,12 @@ class Inspector:
|
||||
|
||||
###
|
||||
|
||||
|
||||
class ModuleInspector(Inspector):
|
||||
def namedParts(self):
|
||||
return ['__dict__']
|
||||
|
||||
|
||||
class ClassInspector(Inspector):
|
||||
def namedParts(self):
|
||||
return ['__bases__'] + list(self.object.__dict__.keys())
|
||||
@@ -161,34 +163,41 @@ class ClassInspector(Inspector):
|
||||
def title(self):
|
||||
return self.object.__name__ + ' Class'
|
||||
|
||||
|
||||
class InstanceInspector(Inspector):
|
||||
def title(self):
|
||||
return self.object.__class__.__name__
|
||||
|
||||
def namedParts(self):
|
||||
return ['__class__'] + dir(self.object)
|
||||
|
||||
###
|
||||
|
||||
|
||||
class FunctionInspector(Inspector):
|
||||
def title(self):
|
||||
return self.object.__name__ + "()"
|
||||
|
||||
|
||||
class InstanceMethodInspector(Inspector):
|
||||
def title(self):
|
||||
return str(self.object.__self__.__class__) + "." + self.object.__name__ + "()"
|
||||
|
||||
|
||||
class CodeInspector(Inspector):
|
||||
def title(self):
|
||||
return str(self.object)
|
||||
|
||||
###
|
||||
|
||||
|
||||
class ComplexInspector(Inspector):
|
||||
def namedParts(self):
|
||||
return ['real', 'imag']
|
||||
|
||||
###
|
||||
|
||||
|
||||
class DictionaryInspector(Inspector):
|
||||
|
||||
def initializePartsList(self):
|
||||
@@ -208,6 +217,7 @@ class DictionaryInspector(Inspector):
|
||||
else:
|
||||
return getattr(self.object, key)
|
||||
|
||||
|
||||
class SequenceInspector(Inspector):
|
||||
def initializePartsList(self):
|
||||
Inspector.initializePartsList(self)
|
||||
@@ -224,6 +234,7 @@ class SequenceInspector(Inspector):
|
||||
else:
|
||||
return getattr(self.object, index)
|
||||
|
||||
|
||||
class SliceInspector(Inspector):
|
||||
def namedParts(self):
|
||||
return ['start', 'stop', 'step']
|
||||
@@ -232,6 +243,7 @@ class SliceInspector(Inspector):
|
||||
### Initialization
|
||||
initializeInspectorMap()
|
||||
|
||||
|
||||
class InspectorWindow:
|
||||
def __init__(self, inspector):
|
||||
self.inspectors = [inspector]
|
||||
@@ -346,8 +358,8 @@ class InspectorWindow:
|
||||
command = self.commandWidget.get(commandStart,
|
||||
commandStart + ' lineend')
|
||||
if command:
|
||||
partDict = { 'this': self.selectedPart(),
|
||||
'object': self.topInspector().object }
|
||||
partDict = {'this': self.selectedPart(),
|
||||
'object': self.topInspector().object}
|
||||
result = eval(command, partDict)
|
||||
self.commandWidget.insert(tk.INSERT, repr(result) + '\n>>> ')
|
||||
self.commandWidget.see(tk.INSERT)
|
||||
@@ -395,7 +407,7 @@ class InspectorWindow:
|
||||
text = tk.Label(
|
||||
frame, justify = tk.LEFT,
|
||||
text = "ListBox shows selected object's attributes\nDouble click or use right arrow on an instance variable to dive down.\nDouble click self or use left arrow to pop back up.\nUse up and down arrow keys to move from item to item in the current level.\n\nValue box (upper right) shows current value of selected item\n\nCommand box (lower right) is used to evaluate python commands\nLocal variables 'object' and 'this' are defined as the current object being inspected\nand the current attribute selected."
|
||||
)
|
||||
)
|
||||
text.pack()
|
||||
|
||||
#Private
|
||||
|
||||
@@ -46,6 +46,7 @@ PRF_UTILITIES = [
|
||||
'lambda s = self: s.playbackMarker.setZ(render, 0.0)',
|
||||
'lambda s = self: s.followTerrain(10.0)']
|
||||
|
||||
|
||||
class MopathRecorder(AppShell, DirectObject):
|
||||
# Override class variables here
|
||||
appname = 'Mopath Recorder Panel'
|
||||
@@ -63,7 +64,7 @@ class MopathRecorder(AppShell, DirectObject):
|
||||
('title', self.appname, None),
|
||||
('nodePath', None, None),
|
||||
('name', name, None)
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Call superclass initialization function
|
||||
@@ -191,7 +192,7 @@ class MopathRecorder(AppShell, DirectObject):
|
||||
('DIRECT_manipulateObjectStart', self.manipulateObjectStartHook),
|
||||
('DIRECT_manipulateObjectCleanup',
|
||||
self.manipulateObjectCleanupHook),
|
||||
]
|
||||
]
|
||||
for event, method in self.actionEvents:
|
||||
self.accept(event, method)
|
||||
|
||||
@@ -930,6 +931,7 @@ class MopathRecorder(AppShell, DirectObject):
|
||||
|
||||
def disableKeyframeButton(self):
|
||||
self.getWidget('Recording', 'Add Keyframe')['state'] = 'disabled'
|
||||
|
||||
def enableKeyframeButton(self):
|
||||
self.getWidget('Recording', 'Add Keyframe')['state'] = 'normal'
|
||||
|
||||
@@ -1211,7 +1213,7 @@ class MopathRecorder(AppShell, DirectObject):
|
||||
else:
|
||||
# Good eval but not a node path, give up
|
||||
nodePath = None
|
||||
except:
|
||||
except Exception:
|
||||
# Bogus eval
|
||||
nodePath = None
|
||||
# Clear bogus entry from listbox
|
||||
|
||||
@@ -66,7 +66,7 @@ class ParticlePanel(AppShell):
|
||||
INITOPT = Pmw.INITOPT
|
||||
optiondefs = (
|
||||
('title', self.appname, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Record particle effect
|
||||
@@ -113,7 +113,6 @@ class ParticlePanel(AppShell):
|
||||
self.particleEffect)
|
||||
self.forcePagesDict = {}
|
||||
|
||||
|
||||
def createInterface(self):
|
||||
# Handle to the toplevels hull
|
||||
interior = self.interior()
|
||||
@@ -171,6 +170,7 @@ class ParticlePanel(AppShell):
|
||||
self.effectsLabelMenu.add_command(
|
||||
label = 'Place Particle Effect',
|
||||
command = lambda s = self: Placer.place(s.particleEffect))
|
||||
|
||||
def togglePEVis(s = self):
|
||||
if s.particleEffect.isHidden():
|
||||
s.particleEffect.show()
|
||||
@@ -257,7 +257,7 @@ class ParticlePanel(AppShell):
|
||||
'Age in seconds at which the system (vs. particles) should die',
|
||||
self.setSystemLifespan,
|
||||
0.0, None, None)
|
||||
)
|
||||
)
|
||||
self.createFloaters(systemPage, systemFloaterDefs)
|
||||
|
||||
# Checkboxes
|
||||
@@ -327,19 +327,18 @@ class ParticlePanel(AppShell):
|
||||
|
||||
self.createCheckbutton(
|
||||
zSpinPage, 'Z Spin Factory', 'Enable Angular Velocity',
|
||||
("On: angular velocity is used; " +
|
||||
"Off: final angle is used"),
|
||||
'On: angular velocity is used; Off: final angle is used',
|
||||
self.toggleAngularVelocity, 0, side = tk.TOP)
|
||||
|
||||
self.createFloater(
|
||||
zSpinPage, 'Z Spin Factory', 'Angular Velocity',
|
||||
'How fast sprites rotate',
|
||||
command = self.setFactoryZSpinAngularVelocity)
|
||||
'How fast sprites rotate',
|
||||
command = self.setFactoryZSpinAngularVelocity)
|
||||
|
||||
self.createFloater(
|
||||
zSpinPage, 'Z Spin Factory', 'Angular Velocity Spread',
|
||||
'Variation in how fast sprites rotate',
|
||||
command = self.setFactoryZSpinAngularVelocitySpread)
|
||||
'Variation in how fast sprites rotate',
|
||||
command = self.setFactoryZSpinAngularVelocitySpread)
|
||||
|
||||
self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Initial Angle',
|
||||
'Starting angle in degrees',
|
||||
@@ -996,7 +995,7 @@ class ParticlePanel(AppShell):
|
||||
widgets.append(
|
||||
self.createFloater(parent, category, label, balloonHelp,
|
||||
command, min, max, resolution)
|
||||
)
|
||||
)
|
||||
return widgets
|
||||
|
||||
def createFloater(self, parent, category, text, balloonHelp,
|
||||
@@ -1158,7 +1157,7 @@ class ParticlePanel(AppShell):
|
||||
label = effect.getName(),
|
||||
command = (lambda s = self,
|
||||
e = effect: s.selectEffectNamed(e.getName()))
|
||||
)
|
||||
)
|
||||
effectActive = tk.IntVar()
|
||||
effectActive.set(effect.isEnabled())
|
||||
self.effectsEnableMenu.add_checkbutton(
|
||||
@@ -1183,7 +1182,7 @@ class ParticlePanel(AppShell):
|
||||
label = name,
|
||||
command = (lambda s = self,
|
||||
n = name: s.selectParticlesNamed(n))
|
||||
)
|
||||
)
|
||||
particleActive = tk.IntVar()
|
||||
particleActive.set(particle.isEnabled())
|
||||
self.particlesEnableMenu.add_checkbutton(
|
||||
@@ -1208,7 +1207,7 @@ class ParticlePanel(AppShell):
|
||||
label = name,
|
||||
command = (lambda s = self,
|
||||
n = name: s.selectForceGroupNamed(n))
|
||||
)
|
||||
)
|
||||
forceActive = tk.IntVar()
|
||||
forceActive.set(force.isEnabled())
|
||||
self.forceGroupEnableMenu.add_checkbutton(
|
||||
@@ -1379,24 +1378,33 @@ class ParticlePanel(AppShell):
|
||||
self.particles.getLocalVelocityFlag())
|
||||
self.getVariable('System', 'System Grows Older').set(
|
||||
self.particles.getSystemGrowsOlderFlag())
|
||||
|
||||
def setSystemPoolSize(self, value):
|
||||
self.particles.setPoolSize(int(value))
|
||||
|
||||
def setSystemBirthRate(self, value):
|
||||
self.particles.setBirthRate(value)
|
||||
|
||||
def setSystemLitterSize(self, value):
|
||||
self.particles.setLitterSize(int(value))
|
||||
|
||||
def setSystemLitterSpread(self, value):
|
||||
self.particles.setLitterSpread(int(value))
|
||||
|
||||
def setSystemLifespan(self, value):
|
||||
self.particles.setSystemLifespan(value)
|
||||
|
||||
def toggleSystemLocalVelocity(self):
|
||||
self.particles.setLocalVelocityFlag(
|
||||
self.getVariable('System', 'Render Space Velocities').get())
|
||||
|
||||
def toggleSystemGrowsOlder(self):
|
||||
self.particles.setSystemGrowsOlderFlag(
|
||||
self.getVariable('System', 'System Grows Older').get())
|
||||
|
||||
def setSystemPos(self, pos):
|
||||
self.particles.nodePath.setPos(Vec3(pos[0], pos[1], pos[2]))
|
||||
|
||||
def setSystemHpr(self, pos):
|
||||
self.particles.nodePath.setHpr(Vec3(pos[0], pos[1], pos[2]))
|
||||
|
||||
@@ -1427,28 +1435,39 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def setFactoryLifeSpan(self, value):
|
||||
self.particles.factory.setLifespanBase(value)
|
||||
|
||||
def setFactoryLifeSpanSpread(self, value):
|
||||
self.particles.factory.setLifespanSpread(value)
|
||||
|
||||
def setFactoryParticleMass(self, value):
|
||||
self.particles.factory.setMassBase(value)
|
||||
|
||||
def setFactoryParticleMassSpread(self, value):
|
||||
self.particles.factory.setMassSpread(value)
|
||||
|
||||
def setFactoryTerminalVelocity(self, value):
|
||||
self.particles.factory.setTerminalVelocityBase(value)
|
||||
|
||||
def setFactoryTerminalVelocitySpread(self, value):
|
||||
self.particles.factory.setTerminalVelocitySpread(value)
|
||||
# Point Page #
|
||||
# Z Spin Page #
|
||||
|
||||
def setFactoryZSpinInitialAngle(self, angle):
|
||||
self.particles.factory.setInitialAngle(angle)
|
||||
|
||||
def setFactoryZSpinInitialAngleSpread(self, spread):
|
||||
self.particles.factory.setInitialAngleSpread(spread)
|
||||
|
||||
def setFactoryZSpinFinalAngle(self, angle):
|
||||
self.particles.factory.setFinalAngle(angle)
|
||||
|
||||
def setFactoryZSpinFinalAngleSpread(self, spread):
|
||||
self.particles.factory.setFinalAngleSpread(spread)
|
||||
|
||||
def setFactoryZSpinAngularVelocity(self, vel):
|
||||
self.particles.factory.setAngularVelocity(vel)
|
||||
|
||||
def setFactoryZSpinAngularVelocitySpread(self, spread):
|
||||
self.particles.factory.setAngularVelocitySpread(spread)
|
||||
|
||||
@@ -1539,6 +1558,7 @@ class ParticlePanel(AppShell):
|
||||
self.getWidget('Tangent Ring Emitter', 'Radius Spread').set(
|
||||
radiusSpread, 0)
|
||||
# All #
|
||||
|
||||
def setEmissionType(self, newType = None):
|
||||
if newType:
|
||||
type = newType
|
||||
@@ -1601,57 +1621,76 @@ class ParticlePanel(AppShell):
|
||||
self.particles.emitter.setMinBound(Point3(point[0],
|
||||
point[1],
|
||||
point[2]))
|
||||
|
||||
def setEmitterBoxPoint2(self, point):
|
||||
self.particles.emitter.setMaxBound(Point3(point[0],
|
||||
point[1],
|
||||
point[2]))
|
||||
# Disc #
|
||||
|
||||
def setEmitterDiscRadius(self, radius):
|
||||
self.particles.emitter.setRadius(radius)
|
||||
|
||||
def setEmitterDiscInnerAngle(self, angle):
|
||||
self.particles.emitter.setInnerAngle(angle)
|
||||
|
||||
def setEmitterDiscInnerVelocity(self, velocity):
|
||||
self.particles.emitter.setInnerMagnitude(velocity)
|
||||
|
||||
def setEmitterDiscOuterAngle(self, angle):
|
||||
self.particles.emitter.setOuterAngle(angle)
|
||||
|
||||
def setEmitterDiscOuterVelocity(self, velocity):
|
||||
self.particles.emitter.setOuterMagnitude(velocity)
|
||||
|
||||
def toggleEmitterDiscCubicLerping(self):
|
||||
self.particles.emitter.setCubicLerping(
|
||||
self.getVariable('Disc Emitter', 'Cubic Lerping').get())
|
||||
# Line #
|
||||
|
||||
def setEmitterLinePoint1(self, point):
|
||||
self.particles.emitter.setEndpoint1(Point3(point[0],
|
||||
point[1],
|
||||
point[2]))
|
||||
|
||||
def setEmitterLinePoint2(self, point):
|
||||
self.particles.emitter.setEndpoint2(Point3(point[0],
|
||||
point[1],
|
||||
point[2]))
|
||||
# Point #
|
||||
|
||||
def setEmitterPointPosition(self, pos):
|
||||
self.particles.emitter.setLocation(Point3(pos[0], pos[1], pos[2]))
|
||||
# Rectangle #
|
||||
|
||||
def setEmitterRectanglePoint1(self, point):
|
||||
self.particles.emitter.setMinBound(Point2(point[0], point[1]))
|
||||
|
||||
def setEmitterRectanglePoint2(self, point):
|
||||
self.particles.emitter.setMaxBound(Point2(point[0], point[1]))
|
||||
# Ring #
|
||||
|
||||
def setEmitterRingRadius(self, radius):
|
||||
self.particles.emitter.setRadius(radius)
|
||||
|
||||
def setEmitterRingRadiusSpread(self, radiusSpread):
|
||||
self.particles.emitter.setRadiusSpread(radiusSpread)
|
||||
|
||||
def setEmitterRingLaunchAngle(self, angle):
|
||||
self.particles.emitter.setAngle(angle)
|
||||
# Sphere surface #
|
||||
|
||||
def setEmitterSphereSurfaceRadius(self, radius):
|
||||
self.particles.emitter.setRadius(radius)
|
||||
# Sphere volume #
|
||||
|
||||
def setEmitterSphereVolumeRadius(self, radius):
|
||||
self.particles.emitter.setRadius(radius)
|
||||
# Tangent ring #
|
||||
|
||||
def setEmitterTangentRingRadius(self, radius):
|
||||
self.particles.emitter.setRadius(radius)
|
||||
|
||||
def setEmitterTangentRingRadiusSpread(self, radiusSpread):
|
||||
self.particles.emitter.setRadiusSpread(radiusSpread)
|
||||
|
||||
@@ -1849,13 +1888,16 @@ class ParticlePanel(AppShell):
|
||||
self.particles.renderer.setHeadColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setRendererLineTailColor(self, color):
|
||||
self.particles.renderer.setTailColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setRendererLineScaleFactor(self, sf):
|
||||
self.particles.renderer.setLineScaleFactor(sf)
|
||||
# Geom #
|
||||
|
||||
def setRendererGeomNode(self, event):
|
||||
node = None
|
||||
nodePath = base.loader.loadModel(self.rendererGeomNode.get())
|
||||
@@ -1865,16 +1907,20 @@ class ParticlePanel(AppShell):
|
||||
self.particles.geomReference = self.rendererGeomNode.get()
|
||||
self.particles.renderer.setGeomNode(node)
|
||||
# Point #
|
||||
|
||||
def setRendererPointSize(self, size):
|
||||
self.particles.renderer.setPointSize(size)
|
||||
|
||||
def setRendererPointStartColor(self, color):
|
||||
self.particles.renderer.setStartColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setRendererPointEndColor(self, color):
|
||||
self.particles.renderer.setEndColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def rendererPointSelectBlendType(self, blendType):
|
||||
if blendType == "PP_ONE_COLOR":
|
||||
bType = PointParticleRenderer.PPONECOLOR
|
||||
@@ -1883,6 +1929,7 @@ class ParticlePanel(AppShell):
|
||||
elif blendType == "PP_BLEND_VEL":
|
||||
bType = PointParticleRenderer.PPBLENDVEL
|
||||
self.particles.renderer.setBlendType(bType)
|
||||
|
||||
def rendererPointSelectBlendMethod(self, blendMethod):
|
||||
if blendMethod == "PP_NO_BLEND":
|
||||
bMethod = BaseParticleRenderer.PPNOBLEND
|
||||
@@ -1892,18 +1939,23 @@ class ParticlePanel(AppShell):
|
||||
bMethod = BaseParticleRenderer.PPBLENDCUBIC
|
||||
self.particles.renderer.setBlendMethod(bMethod)
|
||||
# Sparkle #
|
||||
|
||||
def setRendererSparkleCenterColor(self, color):
|
||||
self.particles.renderer.setCenterColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setRendererSparkleEdgeColor(self, color):
|
||||
self.particles.renderer.setEdgeColor(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setRendererSparkleBirthRadius(self, radius):
|
||||
self.particles.renderer.setBirthRadius(radius)
|
||||
|
||||
def setRendererSparkleDeathRadius(self, radius):
|
||||
self.particles.renderer.setDeathRadius(radius)
|
||||
|
||||
def setRendererSparkleLifeScale(self, lifeScaleMethod):
|
||||
if lifeScaleMethod == 'SP_NO_SCALE':
|
||||
lScale = SparkleParticleRenderer.SPNOSCALE
|
||||
@@ -1911,6 +1963,7 @@ class ParticlePanel(AppShell):
|
||||
lScale = SparkleParticleRenderer.SPSCALE
|
||||
self.particles.renderer.setLifeScale(lScale)
|
||||
# Sprite #
|
||||
|
||||
def setSpriteSourceType(self):
|
||||
if self.rendererSpriteSourceType.get() == 0:
|
||||
self.rendererSpriteTextureEntry['state'] = 'normal'
|
||||
@@ -1929,9 +1982,11 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def setRendererSpriteAnimationFrameRate(self, rate):
|
||||
self.particles.renderer.setAnimateFramesRate(rate)
|
||||
|
||||
def setRendererSpriteAnimationEnable(self):
|
||||
self.particles.renderer.setAnimateFramesEnable(
|
||||
self.getVariable('Sprite Renderer','Enable Animation').get())
|
||||
|
||||
def addRendererSpriteAnimationTexture(self):
|
||||
ren = self.particles.getRenderer()
|
||||
parent = self.rendererSpriteAnimationFrame
|
||||
@@ -1953,6 +2008,7 @@ class ParticlePanel(AppShell):
|
||||
self.rendererSpriteAnimationWidgetList.append(
|
||||
self.createSpriteAnimationTextureWidget(parent, anim, repr(frameNum)))
|
||||
parent.pack(fill=tk.BOTH, expand=1)
|
||||
|
||||
def addRendererSpriteAnimationFromNode(self):
|
||||
ren = self.particles.getRenderer()
|
||||
parent = self.rendererSpriteAnimationFrame
|
||||
@@ -1978,9 +2034,11 @@ class ParticlePanel(AppShell):
|
||||
def toggleRendererSpriteXScale(self):
|
||||
self.particles.renderer.setXScaleFlag(
|
||||
self.getVariable('Sprite Renderer', 'X Scale').get())
|
||||
|
||||
def toggleRendererSpriteYScale(self):
|
||||
self.particles.renderer.setYScaleFlag(
|
||||
self.getVariable('Sprite Renderer', 'Y Scale').get())
|
||||
|
||||
def toggleRendererSpriteAnimAngle(self):
|
||||
self.particles.renderer.setAnimAngleFlag(
|
||||
self.getVariable('Sprite Renderer', 'Anim Angle').get())
|
||||
@@ -1991,14 +2049,19 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def setRendererSpriteInitialXScale(self, xScale):
|
||||
self.particles.renderer.setInitialXScale(xScale)
|
||||
|
||||
def setRendererSpriteFinalXScale(self, xScale):
|
||||
self.particles.renderer.setFinalXScale(xScale)
|
||||
|
||||
def setRendererSpriteInitialYScale(self, yScale):
|
||||
self.particles.renderer.setInitialYScale(yScale)
|
||||
|
||||
def setRendererSpriteFinalYScale(self, yScale):
|
||||
self.particles.renderer.setFinalYScale(yScale)
|
||||
|
||||
def setRendererSpriteNonAnimatedTheta(self, theta):
|
||||
self.particles.renderer.setNonanimatedTheta(theta)
|
||||
|
||||
def setRendererSpriteBlendMethod(self, blendMethod):
|
||||
if blendMethod == 'PP_NO_BLEND':
|
||||
bMethod = BaseParticleRenderer.PPNOBLEND
|
||||
@@ -2008,9 +2071,11 @@ class ParticlePanel(AppShell):
|
||||
bMethod = BaseParticleRenderer.PPBLENDCUBIC
|
||||
else:
|
||||
bMethod = BaseParticleRenderer.PPNOBLEND
|
||||
|
||||
def toggleRendererSpriteAlphaDisable(self):
|
||||
self.particles.renderer.setAlphaDisable(
|
||||
self.getVariable('Sprite Renderer', 'Alpha Disable').get())
|
||||
|
||||
def setRendererColorBlendAttrib(self, rendererName, blendMethodStr, incomingOperandStr, fbufferOperandStr):
|
||||
self.particles.getRenderer().setColorBlendMode(getattr(ColorBlendAttrib, blendMethodStr),
|
||||
getattr(ColorBlendAttrib, incomingOperandStr),
|
||||
@@ -2024,48 +2089,56 @@ class ParticlePanel(AppShell):
|
||||
self.getWidget(rendererName,'Fbuffer Op.').pack_forget()
|
||||
|
||||
self.updateRendererWidgets()
|
||||
|
||||
def setRendererSpriteColorBlendMethod(self, blendMethod):
|
||||
blendMethodStr = blendMethod
|
||||
incomingOperandStr = self.getVariable('Sprite Renderer','Incoming Op.').get()
|
||||
fbufferOperandStr = self.getVariable('Sprite Renderer','Fbuffer Op.').get()
|
||||
|
||||
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
|
||||
|
||||
def setRendererSpriteColorBlendIncomingOperand(self, operand):
|
||||
blendMethodStr = self.getVariable('Sprite Renderer','Color Blend').get()
|
||||
incomingOperandStr = operand
|
||||
fbufferOperandStr = self.getVariable('Sprite Renderer','Fbuffer Op.').get()
|
||||
|
||||
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
|
||||
|
||||
def setRendererSpriteColorBlendFbufferOperand(self, operand):
|
||||
blendMethodStr = self.getVariable('Sprite Renderer','Color Blend').get()
|
||||
incomingOperandStr = self.getVariable('Sprite Renderer','Incoming Op.').get()
|
||||
fbufferOperandStr = operand
|
||||
self.setRendererColorBlendAttrib('Sprite Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
|
||||
|
||||
|
||||
# GeomParticleRenderer Functionality
|
||||
|
||||
def toggleRendererGeomXScale(self):
|
||||
self.particles.renderer.setXScaleFlag(
|
||||
self.getVariable('Geom Renderer', 'X Scale').get())
|
||||
|
||||
def toggleRendererGeomYScale(self):
|
||||
self.particles.renderer.setYScaleFlag(
|
||||
self.getVariable('Geom Renderer', 'Y Scale').get())
|
||||
|
||||
def toggleRendererGeomZScale(self):
|
||||
self.particles.renderer.setZScaleFlag(
|
||||
self.getVariable('Geom Renderer', 'Z Scale').get())
|
||||
|
||||
def setRendererGeomInitialXScale(self, xScale):
|
||||
self.particles.renderer.setInitialXScale(xScale)
|
||||
|
||||
def setRendererGeomFinalXScale(self, xScale):
|
||||
self.particles.renderer.setFinalXScale(xScale)
|
||||
|
||||
def setRendererGeomInitialYScale(self, yScale):
|
||||
self.particles.renderer.setInitialYScale(yScale)
|
||||
|
||||
def setRendererGeomFinalYScale(self, yScale):
|
||||
self.particles.renderer.setFinalYScale(yScale)
|
||||
|
||||
def setRendererGeomInitialZScale(self, zScale):
|
||||
self.particles.renderer.setInitialZScale(zScale)
|
||||
|
||||
def setRendererGeomFinalZScale(self, zScale):
|
||||
self.particles.renderer.setFinalZScale(zScale)
|
||||
|
||||
@@ -2087,7 +2160,6 @@ class ParticlePanel(AppShell):
|
||||
fbufferOperandStr = operand
|
||||
self.setRendererColorBlendAttrib('Geom Renderer', blendMethodStr, incomingOperandStr, fbufferOperandStr)
|
||||
|
||||
|
||||
def addConstantInterpolationSegment(self, id = None):
|
||||
ren = self.particles.getRenderer()
|
||||
cim = ren.getColorInterpolationManager()
|
||||
@@ -2187,17 +2259,22 @@ class ParticlePanel(AppShell):
|
||||
def createInterpolationSegmentFrame(self, parent, segName, seg):
|
||||
frame = tk.Frame(parent, relief = tk.RAISED, borderwidth = 2)
|
||||
lFrame = tk.Frame(frame, relief = tk.FLAT)
|
||||
|
||||
def removeInterpolationSegmentFrame(s = self, seg = seg, fr = frame):
|
||||
s.particles.getRenderer().getColorInterpolationManager().clearSegment(seg.getId())
|
||||
fr.pack_forget()
|
||||
|
||||
def setSegEnabled(s=self, n=segName):
|
||||
enabled = s.getVariable('Sprite Renderer', n+' Enabled')
|
||||
seg.setEnabled(enabled.get())
|
||||
|
||||
def setIsModulated(s=self, n=segName):
|
||||
modulated = s.getVariable('Sprite Renderer', n+' isModulated')
|
||||
seg.setIsModulated(modulated.get())
|
||||
|
||||
def setSegBegin(time):
|
||||
seg.setTimeBegin(time)
|
||||
|
||||
def setSegEnd(time):
|
||||
seg.setTimeEnd(time)
|
||||
tk.Button(lFrame, text = 'X',
|
||||
@@ -2236,6 +2313,7 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def createConstantInterpolationSegmentWidget(self, parent, segName, segment):
|
||||
fun = segment.getFunction()
|
||||
|
||||
def setSegColorA(color):
|
||||
fun.setColorA(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
@@ -2255,10 +2333,12 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def createLinearInterpolationSegmentWidget(self, parent, segName, segment):
|
||||
fun = segment.getFunction()
|
||||
|
||||
def setSegColorA(color):
|
||||
fun.setColorA(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setSegColorB(color):
|
||||
fun.setColorB(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
@@ -2284,16 +2364,20 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def createStepwaveInterpolationSegmentWidget(self, parent, segName, segment):
|
||||
fun = segment.getFunction()
|
||||
|
||||
def setColorA(color):
|
||||
fun.setColorA(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setColorB(color):
|
||||
fun.setColorB(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setWidthA(width):
|
||||
fun.setWidthA(width)
|
||||
|
||||
def setWidthB(width):
|
||||
fun.setWidthB(width)
|
||||
|
||||
@@ -2327,14 +2411,17 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def createSinusoidInterpolationSegmentWidget(self, parent, segName, segment):
|
||||
fun = segment.getFunction()
|
||||
|
||||
def setColorA(color):
|
||||
fun.setColorA(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setColorB(color):
|
||||
fun.setColorB(
|
||||
Vec4(color[0]/255.0, color[1]/255.0,
|
||||
color[2]/255.0, color[3]/255.0))
|
||||
|
||||
def setPeriod(period):
|
||||
fun.setPeriod(period)
|
||||
|
||||
@@ -2543,18 +2630,25 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def addLinearVectorForce(self):
|
||||
self.addForce(LinearVectorForce())
|
||||
|
||||
def addLinearFrictionForce(self):
|
||||
self.addForce(LinearFrictionForce())
|
||||
|
||||
def addLinearJitterForce(self):
|
||||
self.addForce(LinearJitterForce())
|
||||
|
||||
def addLinearNoiseForce(self):
|
||||
self.addForce(LinearNoiseForce())
|
||||
|
||||
def addLinearSinkForce(self):
|
||||
self.addForce(LinearSinkForce())
|
||||
|
||||
def addLinearSourceForce(self):
|
||||
self.addForce(LinearSourceForce())
|
||||
|
||||
def addLinearCylinderVortexForce(self):
|
||||
self.addForce(LinearCylinderVortexForce())
|
||||
|
||||
def addLinearUserDefinedForce(self):
|
||||
self.addForce(LinearUserDefinedForce())
|
||||
|
||||
@@ -2650,6 +2744,7 @@ class ParticlePanel(AppShell):
|
||||
def createForceFrame(self, forcePage, forceName, force):
|
||||
frame = tk.Frame(forcePage, relief = tk.RAISED, borderwidth = 2)
|
||||
lFrame = tk.Frame(frame, relief = tk.FLAT)
|
||||
|
||||
def removeForce(s = self, f = force, fr = frame):
|
||||
s.forceGroup.removeForce(f)
|
||||
fr.pack_forget()
|
||||
@@ -2667,9 +2762,11 @@ class ParticlePanel(AppShell):
|
||||
def createLinearForceWidgets(self, frame, pageName, forceName, force):
|
||||
def setAmplitude(amp, f = force):
|
||||
f.setAmplitude(amp)
|
||||
|
||||
def toggleMassDependent(s=self, f=force, p=pageName, n=forceName):
|
||||
v = s.getVariable(p, n+' Mass Dependent')
|
||||
f.setMassDependent(v.get())
|
||||
|
||||
def setVectorMasks(s=self, f=force, p=pageName, n=forceName):
|
||||
xMask = s.getVariable(p, n+' Mask X').get()
|
||||
yMask = s.getVariable(p, n+' Mask Y').get()
|
||||
@@ -2698,6 +2795,7 @@ class ParticlePanel(AppShell):
|
||||
|
||||
def createForceActiveWidget(self, frame, pageName, forceName, force):
|
||||
cbName = forceName + ' Active'
|
||||
|
||||
def toggle(s = self, f = force, p = pageName, n = cbName):
|
||||
s.toggleForce(f, p, n)
|
||||
self.createCheckbutton(frame, pageName, cbName,
|
||||
@@ -2741,10 +2839,13 @@ class ParticlePanel(AppShell):
|
||||
def createLinearCylinderVortexForceWidget(self, forcePage, pageName,
|
||||
count, force):
|
||||
forceName = 'Vortex Force-' + repr(count)
|
||||
|
||||
def setCoef(coef, f = force):
|
||||
f.setCoef(coef)
|
||||
|
||||
def setLength(length, f = force):
|
||||
f.setLength(length)
|
||||
|
||||
def setRadius(radius, f = force):
|
||||
f.setRadius(radius)
|
||||
frame = self.createForceFrame(forcePage, forceName, force)
|
||||
@@ -2775,8 +2876,10 @@ class ParticlePanel(AppShell):
|
||||
if type == 'FT_ONE_OVER_R_CUBED':
|
||||
#f.setFalloffType(LinearDistanceForce.FTONEOVERRCUBED)
|
||||
f.setFalloffType(2)
|
||||
|
||||
def setForceCenter(vec, f = force):
|
||||
f.setForceCenter(Point3(vec[0], vec[1], vec[2]))
|
||||
|
||||
def setRadius(radius, f = force):
|
||||
f.setRadius(radius)
|
||||
forceName = type + ' Force-' + repr(count)
|
||||
@@ -2813,12 +2916,12 @@ class ParticlePanel(AppShell):
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
# Create demo in root window for testing.
|
||||
if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
base
|
||||
except:
|
||||
except NameError:
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
base = ShowBase()
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import tkinter as tk
|
||||
|
||||
#TODO: Task to monitor pose
|
||||
|
||||
|
||||
class Placer(AppShell):
|
||||
# Override class variables here
|
||||
appname = 'Placer Panel'
|
||||
@@ -28,7 +29,7 @@ class Placer(AppShell):
|
||||
optiondefs = (
|
||||
('title', self.appname, None),
|
||||
('nodePath', base.direct.camera, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
# Call superclass initialization function
|
||||
@@ -355,8 +356,8 @@ class Placer(AppShell):
|
||||
self.scaleY['command'] = self.xform
|
||||
self.scaleZ['command'] = self.xform
|
||||
|
||||
|
||||
### WIDGET OPERATIONS ###
|
||||
|
||||
def setMovementMode(self, movementMode):
|
||||
# Set prefix
|
||||
namePrefix = ''
|
||||
@@ -407,7 +408,7 @@ class Placer(AppShell):
|
||||
else:
|
||||
# Good eval but not a node path, give up
|
||||
nodePath = None
|
||||
except:
|
||||
except Exception:
|
||||
# Bogus eval
|
||||
nodePath = None
|
||||
# Clear bogus entry from listbox
|
||||
@@ -464,7 +465,7 @@ class Placer(AppShell):
|
||||
else:
|
||||
# Good eval but not a node path, give up
|
||||
nodePath = None
|
||||
except:
|
||||
except Exception:
|
||||
# Bogus eval
|
||||
nodePath = None
|
||||
# Clear bogus entry from listbox
|
||||
@@ -782,11 +783,13 @@ class Placer(AppShell):
|
||||
self.orbitFromCS.removeNode()
|
||||
self.orbitToCS.removeNode()
|
||||
|
||||
|
||||
def place(nodePath):
|
||||
return Placer(nodePath = nodePath)
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
# Create demo in root window for testing.
|
||||
if __name__ == '__main__':
|
||||
root = Pmw.initialise()
|
||||
|
||||
@@ -21,7 +21,7 @@ class TaskManagerPanel(AppShell):
|
||||
INITOPT = Pmw.INITOPT
|
||||
optiondefs = (
|
||||
('title', self.appname, None),
|
||||
)
|
||||
)
|
||||
self.defineoptions(kw, optiondefs)
|
||||
|
||||
self.taskMgr = taskMgr
|
||||
@@ -38,10 +38,10 @@ class TaskManagerPanel(AppShell):
|
||||
self.taskMgrWidget = TaskManagerWidget(
|
||||
self.interior(), self.taskMgr)
|
||||
|
||||
|
||||
def onDestroy(self, event):
|
||||
self.taskMgrWidget.onDestroy()
|
||||
|
||||
|
||||
class TaskManagerWidget(DirectObject):
|
||||
"""
|
||||
TaskManagerWidget class: this class contains methods for creating
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user