direct: More code style changes

This commit is contained in:
rdb
2023-02-22 11:42:13 +01:00
parent 9a15e9245c
commit 37b5c9ad9e
112 changed files with 1312 additions and 775 deletions
+9 -2
View File
@@ -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
+5 -23
View File
@@ -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
+12 -12
View File
@@ -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),
}
],
}
],
}
+2 -10
View File
@@ -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
+2 -5
View File
@@ -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)
+14 -3
View File
@@ -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
+2 -1
View File
@@ -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
+26 -26
View File
@@ -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:
+2 -2
View File
@@ -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)
+6 -1
View File
@@ -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)
+10 -1
View File
@@ -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())
+9 -7
View File
@@ -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)
+10 -6
View File
@@ -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:
+5 -6
View File
@@ -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
+6 -7
View File
@@ -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
+59 -58
View File
@@ -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
+4 -2
View File
@@ -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]
+7 -11
View File
@@ -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
+2 -3
View File
@@ -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]
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -48,7 +48,7 @@ class PyDatagram(Datagram):
STString: (Datagram.addString, None),
STBlob: (Datagram.addBlob, None),
STBlob32: (Datagram.addBlob32, None),
}
}
addChannel = Datagram.addUint64
+1 -1
View File
@@ -46,7 +46,7 @@ class PyDatagramIterator(DatagramIterator):
STString: DatagramIterator.getString,
STBlob: DatagramIterator.getBlob,
STBlob32: DatagramIterator.getBlob32,
}
}
getChannel = DatagramIterator.getUint64
+1 -1
View File
@@ -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:
+1 -3
View File
@@ -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)
+1 -1
View File
@@ -115,7 +115,7 @@ class FourState:
self.enterState4,
self.exitState4,
[names[1]]),
}
}
self.fsm = ClassicFSM.ClassicFSM('FourState',
list(self.states.values()),
# Initial State
+1 -1
View File
@@ -123,7 +123,7 @@ class FourStateAI:
self.enterState4,
self.exitState4,
[names[1]]),
}
}
self.fsm = ClassicFSM.ClassicFSM('FourState',
list(self.states.values()),
# Initial State
+1 -1
View File
@@ -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))
+3 -1
View File
@@ -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)
+2 -2
View File
@@ -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']
+3 -2
View File
@@ -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:
+12 -7
View File
@@ -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)
+3 -1
View File
@@ -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()
+1 -3
View File
@@ -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
+4 -3
View File
@@ -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
+3 -1
View File
@@ -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)
+2 -1
View File
@@ -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
+3 -2
View File
@@ -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'])):
+4 -3
View File
@@ -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)
+2 -1
View File
@@ -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)
+3 -3
View File
@@ -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
+4 -3
View File
@@ -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)
+2 -2
View File
@@ -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
+2 -1
View File
@@ -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):
+2 -2
View File
@@ -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 *
+31 -10
View File
@@ -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)
+13 -13
View File
@@ -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):
+38 -35
View File
@@ -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)
+4 -3
View File
@@ -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 = []
+1 -1
View File
@@ -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)
+26 -24
View File
@@ -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)
+6 -6
View File
@@ -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)
+3 -4
View File
@@ -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
+40 -32
View File
@@ -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))
+3 -1
View File
@@ -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
+14 -14
View File
@@ -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'):
+2 -1
View File
@@ -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', {})),
+21 -15
View File
@@ -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
+31 -19
View File
@@ -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)
+6 -6
View File
@@ -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
+3 -1
View File
@@ -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)
+1 -1
View File
@@ -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')
+6 -6
View File
@@ -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()
+1 -1
View File
@@ -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
+17 -18
View File
@@ -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)
+46 -22
View File
@@ -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()
+12 -11
View File
@@ -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:
+6 -5
View File
@@ -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 -3
View File
@@ -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
+13 -7
View File
@@ -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.
+10 -2
View File
@@ -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:
+2 -14
View File
@@ -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:
+3 -5
View File
@@ -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)
+1 -1
View File
@@ -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()
+6 -3
View File
@@ -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:
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+3 -2
View File
@@ -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"""
+2 -2
View File
@@ -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
+5 -4
View File
@@ -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
+5 -6
View File
@@ -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'),
+5 -3
View File
@@ -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
+1 -10
View File
@@ -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
+9 -1
View File
@@ -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:
+13 -1
View 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
+25 -2
View File
@@ -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
View File
@@ -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
+6 -5
View File
@@ -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
+5 -5
View File
@@ -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,
+3 -3
View File
@@ -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 ' +
+20 -8
View File
@@ -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
+5 -3
View File
@@ -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
+120 -17
View File
@@ -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()
+7 -4
View File
@@ -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()
+2 -2
View File
@@ -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