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

View File

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

View File

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

View File

@ -471,11 +471,7 @@ class TaskManager:
if TaskManager.notify.getDebug():
TaskManager.notify.debug('__addPendingTask: %s' % (task.name))
pri = task.getPriority()
if self.pendingTaskDict.has_key(pri):
taskPriList = self.pendingTaskDict[pri]
else:
taskPriList = TaskPriorityList(pri)
self.pendingTaskDict[pri] = taskPriList
taskPriList = self.pendingTaskDict.setdefault(pri, TaskPriorityList(pri))
taskPriList.add(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
// Access: Published

View File

@ -64,6 +64,10 @@ PUBLISHED:
void unstash();
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 write(ostream &out, int indent_level = 0) const;