toon optimizations

This commit is contained in:
Joe Shochet 2004-06-14 18:08:17 +00:00
parent a5445eddc1
commit 15db33d2ff
6 changed files with 156 additions and 169 deletions

View File

@ -578,16 +578,11 @@ class Actor(PandaObject, NodePath):
"""getPart(self, string, key="lodRoot") """getPart(self, string, key="lodRoot")
Find the named part in the optional named lod and return it, or Find the named part in the optional named lod and return it, or
return None if not present""" return None if not present"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return None
return partBundleDict.get(partName)
if (partBundleDict.has_key(partName)):
return partBundleDict[partName]
else:
return None
def removePart(self, partName, lodName="lodRoot"): def removePart(self, partName, lodName="lodRoot"):
"""removePart(self, string, key="lodRoot") """removePart(self, string, key="lodRoot")
@ -595,18 +590,16 @@ class Actor(PandaObject, NodePath):
optional named lod if present. optional named lod if present.
NOTE: this will remove child geometry also!""" NOTE: this will remove child geometry also!"""
# find the corresponding part bundle dict # find the corresponding part bundle dict
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return
# find the corresponding anim control dict # find the corresponding anim control dict
if (self.__animControlDict.has_key(lodName)): animControlDict = self.__animControlDict.get(lodName)
animControlDict = self.__animControlDict[lodName] if not animControlDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return
# remove the part # remove the part
if (partBundleDict.has_key(partName)): if (partBundleDict.has_key(partName)):
@ -622,14 +615,13 @@ class Actor(PandaObject, NodePath):
Make the given part of the optionally given lod not render, Make the given part of the optionally given lod not render,
even though still in the tree. even though still in the tree.
NOTE: this will affect child geometry""" NOTE: this will affect child geometry"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return
part = partBundleDict.get(partName)
if (partBundleDict.has_key(partName)): if part:
partBundleDict[partName].hide() part.hide()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
@ -637,14 +629,13 @@ class Actor(PandaObject, NodePath):
"""showPart(self, string, key="lodRoot") """showPart(self, string, key="lodRoot")
Make the given part render while in the tree. Make the given part render while in the tree.
NOTE: this will affect child geometry""" NOTE: this will affect child geometry"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return
part = partBundleDict.get(partName)
if (partBundleDict.has_key(partName)): if part:
partBundleDict[partName].show() part.show()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
@ -652,18 +643,14 @@ class Actor(PandaObject, NodePath):
"""showAllParts(self, string, key="lodRoot") """showAllParts(self, string, key="lodRoot")
Make the given part and all its children render while in the tree. Make the given part and all its children render while in the tree.
NOTE: this will affect child geometry""" NOTE: this will affect child geometry"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return
part = partBundleDict.get(partName)
if (partBundleDict.has_key(partName)): if part:
partBundleDict[partName].show() part.show()
children = partBundleDict[partName].getChildren() part.getChildren().show()
numChildren = children.getNumPaths()
for childNum in range(0, numChildren):
(children.getPath(childNum)).show()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
@ -673,15 +660,14 @@ class Actor(PandaObject, NodePath):
animates, it will transform the node by the corresponding animates, it will transform the node by the corresponding
amount. This will replace whatever matrix is on the node each amount. This will replace whatever matrix is on the node each
frame.""" frame."""
partBundleDict = self.__partBundleDict.get(lodName)
if (self.__partBundleDict.has_key(lodName)): if not partBundleDict:
partBundleDict = self.__partBundleDict[lodName]
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return None
if (partBundleDict.has_key(partName)): part = partBundleDict.get(partName)
bundle = partBundleDict[partName].node().getBundle() if part:
bundle = part.node().getBundle()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
return None return None
@ -704,14 +690,14 @@ class Actor(PandaObject, NodePath):
Stops the joint from animating external nodes. If the joint Stops the joint from animating external nodes. If the joint
is animating a transform on a node, this will permanently stop is animating a transform on a node, this will permanently stop
it. However, this does not affect vertex animations.""" it. However, this does not affect vertex animations."""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if not partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return None
if (partBundleDict.has_key(partName)): part = partBundleDict.get(partName)
bundle = partBundleDict[partName].node().getBundle() if part:
bundle = part.node().getBundle()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
return None return None
@ -737,14 +723,14 @@ class Actor(PandaObject, NodePath):
animation has been loaded and bound to the character, it will animation has been loaded and bound to the character, it will
be too late to add a new control during that animation. be too late to add a new control during that animation.
""" """
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if partBundleDict:
else:
Actor.notify.warning("no lod named: %s" % (lodName)) Actor.notify.warning("no lod named: %s" % (lodName))
return None return None
if (partBundleDict.has_key(partName)): part = partBundleDict.get(partName)
bundle = partBundleDict[partName].node().getBundle() if part:
bundle = part.node().getBundle()
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
return None return None
@ -767,36 +753,39 @@ class Actor(PandaObject, NodePath):
return node return node
def instance(self, path, part, jointName, lodName="lodRoot"): def instance(self, path, partName, jointName, lodName="lodRoot"):
"""instance(self, NodePath, string, string, key="lodRoot") """instance(self, NodePath, string, string, key="lodRoot")
Instance a nodePath to an actor part at a joint called jointName""" Instance a nodePath to an actor part at a joint called jointName"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if partBundleDict:
if (partBundleDict.has_key(part)): part = partBundleDict.get(partName)
joint = partBundleDict[part].find("**/" + jointName) if part:
joint = part.find("**/" + jointName)
if (joint.isEmpty()): if (joint.isEmpty()):
Actor.notify.warning("%s not found!" % (jointName)) Actor.notify.warning("%s not found!" % (jointName))
else: else:
return path.instanceTo(joint) return path.instanceTo(joint)
else: else:
Actor.notify.warning("no part named %s!" % (part)) Actor.notify.warning("no part named %s!" % (partName))
else: else:
Actor.notify.warning("no lod named %s!" % (lodName)) Actor.notify.warning("no lod named %s!" % (lodName))
def attach(self, partName, anotherPart, jointName, lodName="lodRoot"): def attach(self, partName, anotherPartName, jointName, lodName="lodRoot"):
"""attach(self, string, string, string, key="lodRoot") """attach(self, string, string, string, key="lodRoot")
Attach one actor part to another at a joint called jointName""" Attach one actor part to another at a joint called jointName"""
if (self.__partBundleDict.has_key(lodName)): partBundleDict = self.__partBundleDict.get(lodName)
partBundleDict = self.__partBundleDict[lodName] if partBundleDict:
if (partBundleDict.has_key(partName)): part = partBundleDict.get(partName)
if (partBundleDict.has_key(anotherPart)): if part:
joint = partBundleDict[anotherPart].find("**/" + jointName) anotherPart = partBundleDict.get(anotherPartName)
if anotherPart:
joint = anotherPart.find("**/" + jointName)
if (joint.isEmpty()): if (joint.isEmpty()):
Actor.notify.warning("%s not found!" % (jointName)) Actor.notify.warning("%s not found!" % (jointName))
else: else:
partBundleDict[partName].reparentTo(joint) part.reparentTo(joint)
else: else:
Actor.notify.warning("no part named %s!" % (anotherPart)) Actor.notify.warning("no part named %s!" % (anotherPartName))
else: else:
Actor.notify.warning("no part named %s!" % (partName)) Actor.notify.warning("no part named %s!" % (partName))
else: else:
@ -1210,24 +1199,11 @@ class Actor(PandaObject, NodePath):
for animName in anims.keys(): for animName in anims.keys():
# make sure this lod in in anim control dict # make sure this lod in in anim control dict
if not (self.__animControlDict.has_key(lodName)): self.__animControlDict.setdefault(lodName, {})
lodDict = {} self.__animControlDict[lodName].setdefault(partName, {})
self.__animControlDict[lodName] = lodDict
# make sure this part dict exists
if not (self.__animControlDict[lodName].has_key(partName)):
partDict = {}
self.__animControlDict[lodName][partName] = partDict
# make sure this an anim dict exists
if not (len(self.__animControlDict[lodName][partName].keys())):
animDict = {}
self.__animControlDict[lodName][partName] = animDict
# store the file path and None in place of the animControl. # store the file path and None in place of the animControl.
# we will bind it only when played # we will bind it only when played
self.__animControlDict[lodName][partName][animName] = \ self.__animControlDict[lodName][partName][animName] = [anims[animName], None]
[anims[animName], None]
def unloadAnims(self, anims, partName="modelRoot", lodName="lodRoot"): def unloadAnims(self, anims, partName="modelRoot", lodName="lodRoot"):
@ -1308,9 +1284,7 @@ class Actor(PandaObject, NodePath):
anim = loader.loadModelOnce(animPath) anim = loader.loadModelOnce(animPath)
if anim == None: if anim == None:
return None return None
animBundle = \ animBundle = (anim.find("**/+AnimBundleNode").node()).getBundle()
(anim.find("**/+AnimBundleNode").node()).getBundle()
bundle = self.__partBundleDict[lodName][partName].node().getBundle() bundle = self.__partBundleDict[lodName][partName].node().getBundle()
# Are there any controls requested for joints in this bundle? # Are there any controls requested for joints in this bundle?

View File

@ -97,14 +97,6 @@ class ClassicFSM(DirectObject):
self.__enter(self.__initialState, argList) self.__enter(self.__initialState, argList)
assert(not self.__internalStateInFlux) assert(not self.__internalStateInFlux)
# Jesse decided that simpler was better with the __str__ function
def __str_not__(self):
"""__str__(self)"""
return "ClassicFSM: name = %s \n states = %s \n initial = %s \n final = %s \n current = %s" \
% (self.__name, self.__states, self.__initialState,
self.__finalState, self.__currentState)
# setters and getters # setters and getters
def getName(self): def getName(self):
@ -115,14 +107,17 @@ class ClassicFSM(DirectObject):
self.__name = name self.__name = name
def getStates(self): def getStates(self):
return(self.__states) return self.__states.values()
def setStates(self, states): def setStates(self, states):
"""setStates(self, State[])""" """setStates(self, State[])"""
self.__states = states # Make a dictionary from stateName -> state
self.__states = {}
for state in states:
self.__states[state.getName()] = state
def addState(self, state): def addState(self, state):
self.__states.append(state) self.__states[state.getName()] = state
def getInitialState(self): def getInitialState(self):
return(self.__initialState) return(self.__initialState)
@ -150,11 +145,12 @@ class ClassicFSM(DirectObject):
def getStateNamed(self, stateName): def getStateNamed(self, stateName):
"""getStateNamed(self, string) """getStateNamed(self, string)
Return the state with given name if found, issue warning otherwise""" Return the state with given name if found, issue warning otherwise"""
for state in self.__states: state = self.__states.get(stateName)
if (state.getName() == stateName): if state:
return state return state
else:
ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" % ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" %
(self.__name, str(stateName))) (self.__name, stateName))
# basic ClassicFSM functionality # basic ClassicFSM functionality
@ -163,9 +159,7 @@ class ClassicFSM(DirectObject):
"""__exitCurrent(self) """__exitCurrent(self)
Exit the current state""" Exit the current state"""
assert(self.__internalStateInFlux) assert(self.__internalStateInFlux)
if ClassicFSM.notify.getDebug(): assert(ClassicFSM.notify.debug("[%s]: exiting %s" % (self.__name, self.__currentState.getName())))
ClassicFSM.notify.debug("[%s]: exiting %s" % (self.__name,
self.__currentState.getName()))
self.__currentState.exit(argList) self.__currentState.exit(argList)
# Only send the state change event if we are inspecting it # Only send the state change event if we are inspecting it
# If this event turns out to be generally useful, we can # If this event turns out to be generally useful, we can
@ -179,17 +173,15 @@ class ClassicFSM(DirectObject):
"""__enter(self, State) """__enter(self, State)
Enter a given state, if it exists""" Enter a given state, if it exists"""
assert(self.__internalStateInFlux) assert(self.__internalStateInFlux)
if (aState in self.__states): stateName = aState.getName()
if ClassicFSM.notify.getDebug(): if (stateName in self.__states):
ClassicFSM.notify.debug("[%s]: entering %s" % (self.__name, assert(ClassicFSM.notify.debug("[%s]: entering %s" % (self.__name, stateName)))
aState.getName()))
self.__currentState = aState self.__currentState = aState
# Only send the state change event if we are inspecting it # Only send the state change event if we are inspecting it
# If this event turns out to be generally useful, we can # If this event turns out to be generally useful, we can
# turn it on all the time, but for now nobody else is using it # turn it on all the time, but for now nobody else is using it
if self.inspecting: if self.inspecting:
messenger.send(self.getName() + '_' + messenger.send(self.getName() + '_' + stateName + '_entered')
aState.getName() + '_entered')
# Once we begin entering the new state, we're allow to # Once we begin entering the new state, we're allow to
# recursively request a transition to another state. # recursively request a transition to another state.
@ -269,24 +261,21 @@ class ClassicFSM(DirectObject):
elif (aStateName == self.__finalState.getName()): elif (aStateName == self.__finalState.getName()):
if (self.__currentState == self.__finalState): if (self.__currentState == self.__finalState):
# Do not do the transition if we are already in the final state # Do not do the transition if we are already in the final state
if ClassicFSM.notify.getDebug(): assert(ClassicFSM.notify.debug("[%s]: already in final state: %s" %
ClassicFSM.notify.debug("[%s]: already in final state: %s" % (self.__name, aStateName)))
(self.__name, aStateName))
return 1 return 1
else: else:
# Force a transition to allow for cleanup # Force a transition to allow for cleanup
if ClassicFSM.notify.getDebug(): assert(ClassicFSM.notify.debug("[%s]: implicit transition to final state: %s" %
ClassicFSM.notify.debug("[%s]: implicit transition to final state: %s" % (self.__name, aStateName)))
(self.__name, aStateName))
self.__transition(aState, self.__transition(aState,
enterArgList, enterArgList,
exitArgList) exitArgList)
return 1 return 1
# are we already in this state? # are we already in this state?
elif (aStateName == self.__currentState.getName()): elif (aStateName == self.__currentState.getName()):
if ClassicFSM.notify.getDebug(): assert(ClassicFSM.notify.debug("[%s]: already in state %s and no self transition" %
ClassicFSM.notify.debug("[%s]: already in state %s and no self transition" % (self.__name, aStateName)))
(self.__name, aStateName))
return 0 return 0
else: else:
msg = ("[%s]: no transition exists from %s to %s" % msg = ("[%s]: no transition exists from %s to %s" %
@ -343,8 +332,8 @@ class ClassicFSM(DirectObject):
if transitionDefined: if transitionDefined:
return self.request(aStateName, enterArgList, exitArgList) return self.request(aStateName, enterArgList, exitArgList)
else: else:
ClassicFSM.notify.debug("[%s]: condition_request: %s, transition doesnt exist" % assert(ClassicFSM.notify.debug("[%s]: condition_request: %s, transition doesnt exist" %
(self.__name, aStateName)) (self.__name, aStateName)))
return 0 return 0
def view(self): def view(self):

View File

@ -81,16 +81,13 @@ class State(DirectObject):
"""__init__(self, string, func, func, string[], inspectorPos = []) """__init__(self, string, func, func, string[], inspectorPos = [])
State constructor: takes name, enter func, exit func, and State constructor: takes name, enter func, exit func, and
a list of states it can transition to (or State.Any).""" a list of states it can transition to (or State.Any)."""
self.__enterFunc = None self.__name = name
self.__exitFunc = None self.__enterFunc = enterFunc
self.__exitFunc = exitFunc
self.setName(name) self.__transitions = transitions
self.setEnterFunc(enterFunc)
self.setExitFunc(exitFunc)
self.setTransitions(transitions)
self.setInspectorPos(inspectorPos)
self.__FSMList = [] self.__FSMList = []
if __debug__:
self.setInspectorPos(inspectorPos)
# setters and getters # setters and getters
@ -106,6 +103,7 @@ class State(DirectObject):
"""getEnterFunc(self)""" """getEnterFunc(self)"""
return(self.__enterFunc) return(self.__enterFunc)
if __debug__:
def redefineFunc(self, oldMethod, newMethod, map): def redefineFunc(self, oldMethod, newMethod, map):
if not FsmRedefine: if not FsmRedefine:
return return
@ -127,6 +125,7 @@ class State(DirectObject):
map[newMethod] = stateList map[newMethod] = stateList
def setEnterFunc(self, stateEnterFunc): def setEnterFunc(self, stateEnterFunc):
if __debug__:
self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap) self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap)
self.__enterFunc = stateEnterFunc self.__enterFunc = stateEnterFunc
@ -136,6 +135,7 @@ class State(DirectObject):
def setExitFunc(self, stateExitFunc): def setExitFunc(self, stateExitFunc):
"""setExitFunc(self, func)""" """setExitFunc(self, func)"""
if __debug__:
self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap) self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap)
self.__exitFunc = stateExitFunc self.__exitFunc = stateExitFunc
@ -176,6 +176,7 @@ class State(DirectObject):
'attempted to add transition %s to state that ' 'attempted to add transition %s to state that '
'transitions to any state') 'transitions to any state')
if __debug__:
def getInspectorPos(self): def getInspectorPos(self):
"""getInspectorPos(self)""" """getInspectorPos(self)"""
return(self.__inspectorPos) return(self.__inspectorPos)
@ -184,7 +185,6 @@ class State(DirectObject):
"""setInspectorPos(self, [x, y])""" """setInspectorPos(self, [x, y])"""
self.__inspectorPos = inspectorPos self.__inspectorPos = inspectorPos
# support for HFSMs # support for HFSMs
def getChildren(self): def getChildren(self):

View File

@ -471,11 +471,7 @@ class TaskManager:
if TaskManager.notify.getDebug(): if TaskManager.notify.getDebug():
TaskManager.notify.debug('__addPendingTask: %s' % (task.name)) TaskManager.notify.debug('__addPendingTask: %s' % (task.name))
pri = task.getPriority() pri = task.getPriority()
if self.pendingTaskDict.has_key(pri): taskPriList = self.pendingTaskDict.setdefault(pri, TaskPriorityList(pri))
taskPriList = self.pendingTaskDict[pri]
else:
taskPriList = TaskPriorityList(pri)
self.pendingTaskDict[pri] = taskPriList
taskPriList.add(task) taskPriList.add(task)
def __addNewTask(self, task): def __addNewTask(self, task):

View File

@ -378,6 +378,30 @@ detach() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: NodePathCollection::set_color
// Access: Published
// Description: Colors all NodePaths in the collection
////////////////////////////////////////////////////////////////////
void NodePathCollection::
set_color(float r, float g, float b, float a, int priority) {
for (int i = 0; i < get_num_paths(); i++) {
get_path(i).set_color(Colorf(r, g, b, a), priority);
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePathCollection::set_color
// Access: Published
// Description: Colors all NodePaths in the collection
////////////////////////////////////////////////////////////////////
void NodePathCollection::
set_color(const Colorf &color, int priority) {
for (int i = 0; i < get_num_paths(); i++) {
get_path(i).node()->set_attrib(ColorAttrib::make_flat(color), priority);
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: NodePathCollection::output // Function: NodePathCollection::output
// Access: Published // Access: Published

View File

@ -64,6 +64,10 @@ PUBLISHED:
void unstash(); void unstash();
void detach(); void detach();
void set_color(float r, float g, float b, float a = 1.0,
int priority = 0);
void set_color(const Colorf &color, int priority = 0);
void output(ostream &out) const; void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const; void write(ostream &out, int indent_level = 0) const;