Browse Source

toon optimizations

Joe Shochet 21 years ago
parent
commit
15db33d2ff

+ 65 - 91
direct/src/actor/Actor.py

@@ -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:
@@ -1206,28 +1195,15 @@ class Actor(PandaObject, NodePath):
         anims in the form animName:animPath{}"""
         
         Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
-                          (anims, partName, lodName))
+                           (anims, partName, lodName))
 
         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?

+ 25 - 36
direct/src/fsm/ClassicFSM.py

@@ -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):
-                return state
-        ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" %
-                           (self.__name, str(stateName)))
+        state = self.__states.get(stateName)
+        if state:
+            return state
+        else:
+            ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" %
+                                      (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):

+ 37 - 37
direct/src/fsm/State.py

@@ -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,28 +103,30 @@ class State(DirectObject):
         """getEnterFunc(self)"""
         return(self.__enterFunc)
 
-    def redefineFunc(self, oldMethod, newMethod, map):
-        if not FsmRedefine:
-            return
-        # Methods are allowed to be None
-        if oldMethod is None:
-            return
-        if map.has_key(oldMethod):
-            # Get the list of states for the old function
-            stateList = map[oldMethod]
-            # Remove this state from that list of states
-            stateList.remove(self)
-            # If the stateList is now empty, remove this entry altogether
-            if not stateList:
-                del(map[oldMethod])
-        # Now add the new function, creating a starter state list
-        # if there is not one already
-        stateList = map.get(newMethod, [])
-        stateList.append(self)
-        map[newMethod] = stateList
+    if __debug__:
+        def redefineFunc(self, oldMethod, newMethod, map):
+            if not FsmRedefine:
+                return
+            # Methods are allowed to be None
+            if oldMethod is None:
+                return
+            if map.has_key(oldMethod):
+                # Get the list of states for the old function
+                stateList = map[oldMethod]
+                # Remove this state from that list of states
+                stateList.remove(self)
+                # If the stateList is now empty, remove this entry altogether
+                if not stateList:
+                    del(map[oldMethod])
+            # Now add the new function, creating a starter state list
+            # if there is not one already
+            stateList = map.get(newMethod, [])
+            stateList.append(self)
+            map[newMethod] = stateList
 
     def setEnterFunc(self, stateEnterFunc):
-        self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap)
+        if __debug__:
+            self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap)
         self.__enterFunc = stateEnterFunc
 
     def getExitFunc(self):
@@ -136,7 +135,8 @@ class State(DirectObject):
 
     def setExitFunc(self, stateExitFunc):
         """setExitFunc(self, func)"""
-        self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap)
+        if __debug__:
+            self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap)
         self.__exitFunc = stateExitFunc
 
     def transitionsToAny(self):
@@ -176,14 +176,14 @@ class State(DirectObject):
                 'attempted to add transition %s to state that '
                 'transitions to any state')
 
-    def getInspectorPos(self):
-        """getInspectorPos(self)"""
-        return(self.__inspectorPos)
-
-    def setInspectorPos(self, inspectorPos):
-        """setInspectorPos(self, [x, y])"""
-        self.__inspectorPos = inspectorPos
+    if __debug__:
+        def getInspectorPos(self):
+            """getInspectorPos(self)"""
+            return(self.__inspectorPos)
 
+        def setInspectorPos(self, inspectorPos):
+            """setInspectorPos(self, [x, y])"""
+            self.__inspectorPos = inspectorPos
 
     # support for HFSMs
 

+ 1 - 5
direct/src/task/Task.py

@@ -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):

+ 24 - 0
panda/src/pgraph/nodePathCollection.cxx

@@ -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

+ 4 - 0
panda/src/pgraph/nodePathCollection.h

@@ -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;