Browse Source

*** empty log message ***

gregw 24 years ago
parent
commit
b02e0c91fb
2 changed files with 145 additions and 76 deletions
  1. 141 75
      direct/src/actor/Actor.py
  2. 4 1
      direct/src/actor/DistributedActor.py

+ 141 - 75
direct/src/actor/Actor.py

@@ -10,7 +10,6 @@ class Actor(PandaObject, NodePath):
     #create the Actor class globals (ewww!)
     notify = directNotify.newCategory("Actor")
     partPrefix = "__Actor_"
-
     
     #special methods
     
@@ -361,13 +360,13 @@ class Actor(PandaObject, NodePath):
         NOTE: Returns info only for the first LOD"""
         # use the first lod
         lodName = self.__animControlDict.keys()[0]
-        
+            
         if (partName==None):
             partName = self.__animControlDict[lodName].keys()[0]
 
         if (animName==None):
             animName = self.getCurrentAnim(partName)
-            
+
         animControl = self.getAnimControl(animName, partName, lodName)
         if (animControl != None):
             return animControl.getPlayRate()
@@ -769,26 +768,23 @@ class Actor(PandaObject, NodePath):
         NOTE: stops all LODs"""
         for lodName in self.__animControlDict.keys():
             animControlDict = self.__animControlDict[lodName]
+            # assemble lists of parts and anims
+            if (partName == None):
+                partNames = animControlDict.keys()
+            else:
+                partNames = [partName]
             if (animName == None):
-                # loop and stop all anims
-                if (partName == None):
-                    # loop over all parts
-                    for thisPart in animControlDict.keys():
-                        for thisAnim in animControlDict[thisPart].keys():
-                            animControlDict[thisPart][thisAnim].stop()
-                else:
-                    # stop just this part
-                    for thisAnim in animControlDict[partName].keys():
-                        animControlDict[partName][thisAnim].stop()
+                animNames = animControlDict[partNames[0]].keys()
             else:
-                # stop the specified anim
-                if (partName == None):
-                    # loop over all parts
-                    for thisPart in animControlDict.keys():
-                        animControlDict[thisPart][animName].stop()
-                else:
-                    animControlDict[partName][animName].stop()
-                    
+                animNames = [animName]
+
+            # loop over all parts
+            for thisPart in partNames:
+                for thisAnim in animNames:
+                    # only stop if it's bound
+                    if isinstance(animControlDict[thisPart][thisAnim],
+                                  AnimControl):
+                            animControlDict[thisPart][thisAnim].stop()
         
     def play(self, animName, partName=None):
         """play(self, string, string=None)
@@ -865,6 +861,8 @@ class Actor(PandaObject, NodePath):
             animControlDict = self.__animControlDict[lodName]
             if (animControlDict.has_key(partName)):
                 if (animControlDict[partName].has_key(animName)):
+                    # make sure the anim is bound first
+                    self.bindAnim(animName, partName, lodName)
                     return animControlDict[partName][animName]
                 else:
                     # anim was not present
@@ -929,7 +927,6 @@ class Actor(PandaObject, NodePath):
 
             model.removeNode()        
 
-
     def loadAnims(self, anims, partName="modelRoot", lodName="lodRoot"):
         """loadAnims(self, string:string{}, string='modelRoot',
         string='lodRoot')
@@ -938,62 +935,125 @@ class Actor(PandaObject, NodePath):
         to 'lodRoot' for non-LOD actors) and dict of corresponding
         anims in the form animName:animPath{}"""
         
-        Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
-                           (anims, partName, lodName))
-
-        animDict = {}
+        #Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
+        #                   (anims, partName, lodName))
 
         for animName in anims.keys():
-            
-            # load the anim and get its anim bundle
-            anim = loader.loadModelOnce(anims[animName])
-            animBundle = \
-                (anim.find("**/+AnimBundleNode").node()).getBundle()
-
-            # bind anim
-            bundleNode = (
-                self.__partBundleDict[lodName][partName]).node()
-                
-            animControl = (bundleNode.getBundle()).bindAnim(animBundle, -1)
-
-            if (animControl == None):
-                Actor.notify.error("Null AnimControl: %s" % (animName))
-            else:
-                animDict[animName] = animControl
-
             # make sure this lod in in anim control dict
             if not (self.__animControlDict.has_key(lodName)):
                 lodDict = {}
                 self.__animControlDict[lodName] = lodDict
 
-            self.__animControlDict[lodName][partName] = animDict
-
-            # clean up after ourselves
-            anim.removeNode()
-            
             # make sure this part dict exists
-            #if not (self.__animControlDict[lodName].has_key(partName)):
-            #    partDict = {}
-            #    self.__animControlDict[lodName][partName] = partDict
+            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
+            if not (len(self.__animControlDict[lodName][partName].keys())):
+                animDict = {}
+                self.__animControlDict[lodName][partName] = animDict
 
-            # add this part's dictionary to animation dictionary
-            #self.__animControlDict[lodName][partName][animName] = animControl
-                
+            # store the file path for now, we assume its been preloaded
+            # and will bind it only when played
+            self.__animControlDict[lodName][partName][animName] = anims[animName]
+
+
+    def unloadAnims(self, anims, partName="modelRoot", lodName="lodRoot"):
+        """unloadAnims(self, string:string{}, string='modelRoot',
+        string='lodRoot')
+        Actor anim unloader. Takes an optional partName (defaults to
+        'modelRoot' for non-multipart actors) and lodName (defaults
+        to 'lodRoot' for non-LOD actors) and dict of corresponding
+        anims in the form animName:animPath{}. Deletes the anim control
+        for the given animation and parts/lods."""
+        
+        Actor.notify.debug("in unloadAnims: %s, part: %s, lod: %s" %
+                           (anims, partName, lodName))
+
+        if (lodName == None):
+            lodNames = self.__animControlDict.keys()
+        else:
+            lodNames = [lodName]
+        if (partName == None):
+            partNames = self.__animControlDict[lodNames[0]].keys()
+        else:
+            partNames = [partName]
+
+        for lodName in lodNames:
+            for partName in partNames:
+                for animName in anims.keys():
+                    # delete the anim control
+                    del(self.__animControlDict[lodName][partName][animName])
+                    # store the filepath for reloading
+                    self.__animControlDict[lodName][partName][animName] = \
+                                                            anims[animName]
+    
+    def bindAnim(self, animName, partName="modelRoot", lodName="lodRoot"):
+        """bindAnim(self, string, string='modelRoot', string='lodRoot')
+        Bind the named animation to the named part and lod
+        """
+
+        if lodName == None:
+            lodNames = self.__animControl.keys()
+        else:
+            lodNames = [lodName]
+        
+        # loop over all lods
+        for thisLod in lodNames:
+            if partName == None:
+                partNames = animControlDict[lodName].keys()
+            else:
+                partNames = [partName]
+            # loop over all parts
+            #animLengths = {}
+            for thisPart in partNames:
+                ac = self.__bindAnimToPart(animName, thisPart, thisLod)
+                #animLengths[partName] = ac.getNumFrames()
+            
+            
+    def __bindAnimToPart(self, animName, partName, lodName):
+        """for internal use only!"""
+        # make sure this anim is in the dict
+        if not self.__animControlDict[lodName][partName].has_key(animName):
+            Actor.notify.debug("actor has no animation %s", animName)
+            
+        # only bind if not already bound!
+        if isinstance(self.__animControlDict[lodName][partName][animName],
+                      AnimControl):
+            return None
+
+        # fetch a copy from the modelPool, or if we weren't careful
+        # enough to preload, fetch from disk :(
+        animPath = self.__animControlDict[lodName][partName][animName]
+        anim = loader.loadModelOnce(animPath)
+        animBundle = \
+                   (anim.find("**/+AnimBundleNode").node()).getBundle()
+
+        # cleanup after ourselves
+        anim.removeNode()
+
+        # bind anim
+        bundleNode = (
+            self.__partBundleDict[lodName][partName]).node()
+        animControl = (bundleNode.getBundle()).bindAnim(animBundle, -1)
+
+        if (animControl == None):
+            Actor.notify.error("Null AnimControl: %s" % (animName))
+        else:
+            # store the animControl
+            self.__animControlDict[lodName][partName][animName] = animControl
+            Actor.notify.debug("binding anim: %s to part: %s, lod: %s" %
+                           (animName, partName, lodName))
+        return animControl
 
     def __copyPartBundles(self, other):
         """__copyPartBundles(self, Actor)
         Copy the part bundle dictionary from another actor as this
         instance's own. NOTE: this method does not actually copy geometry"""
         for lodName in other.__partBundleDict.keys():
-            print "copyPart: lodName:", lodName
             self.__partBundleDict[lodName] = {}            
             for partName in other.__partBundleDict[lodName].keys():
-                print "    partName: ", partName
                 # find the part in our tree
                 partBundle = self.find("**/" + Actor.partPrefix + partName) 
                 if (partBundle != None):
@@ -1011,24 +1071,30 @@ class Actor(PandaObject, NodePath):
         bundles in our part bundle dict that have matching names, and
         store the resulting anim controls in our own part bundle dict"""
         for lodName in other.__animControlDict.keys():
-            print "copyAnim: lodName: ", lodName
             self.__animControlDict[lodName] = {}        
             for partName in other.__animControlDict[lodName].keys():
-                print "    partName: ", partName
                 self.__animControlDict[lodName][partName] = {}
                 for animName in other.__animControlDict[lodName][partName].keys():
-                    print "        anim: ", animName
-                    # get the anim
-                    animBundle = \
-                               other.__animControlDict[lodName][partName][animName].getAnim()
-                    # get the part
-                    partBundleNode = (self.__partBundleDict[lodName][partName].node())
-                    # bind the anim
-                    animControl = \
-                                (partBundleNode.getBundle().bindAnim(animBundle, -1))
-                    if (animControl == None):
-                        Actor.notify.error("Null animControl: %s" % (animName))
+                    # if the anim is bound copy the animControl
+                    if isinstance(
+                        other.__animControlDict[lodName][partName][animName],
+                        AnimControl):
+                        # get the anim
+                        animBundle = \
+                                   other.__animControlDict[lodName][partName][animName].getAnim()
+                        # get the part
+                        partBundleNode = \
+                                       (self.__partBundleDict[lodName][partName].node())
+                        # bind the anim
+                        animControl = \
+                                    (partBundleNode.getBundle().bindAnim(animBundle, -1))
+                        if (animControl == None):
+                            Actor.notify.error("Null animControl: %s" % (animName))
+                        else:
+                            # store the anim control
+                            self.__animControlDict[lodName][partName][animName] = animControl
                     else:
-                        # store the anim control
-                        self.__animControlDict[lodName][partName][animName] = animControl
-                
+                        # else just copy what's there
+                        self.__animControlDict[lodName][partName][animName] = \
+                        other.__animControlDict[lodName][partName][animName]
+

+ 4 - 1
direct/src/actor/DistributedActor.py

@@ -19,4 +19,7 @@ class DistributedActor(DistributedNode.DistributedNode, Actor.Actor):
             
         return None
 
-        
+    def disable(self):
+        # remove anims here
+        print("####\n#### anim dump!\n####")
+        DistributedNode.DistributedNode.disable(self)