Browse Source

loader.asyncFlattenStrong()

David Rose 18 years ago
parent
commit
f36b15fd99
3 changed files with 79 additions and 5 deletions
  1. 0 1
      direct/src/actor/Actor.py
  2. 10 0
      direct/src/interval/LerpInterval.py
  3. 69 4
      direct/src/showbase/Loader.py

+ 0 - 1
direct/src/actor/Actor.py

@@ -308,7 +308,6 @@ class Actor(DirectObject, NodePath):
             else:
                 # just copy these to ourselve
                 otherCopy = other.copyTo(self)
-            self.setGeomNode(otherCopy.getChild(0))
 
             # copy the part dictionary from other
             self.__copyPartBundles(other)

+ 10 - 0
direct/src/interval/LerpInterval.py

@@ -6,6 +6,7 @@ from pandac.PandaModules import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 from direct.showbase import LerpBlendHelpers
+import profile, pstats
 
 #
 # Most of the intervals defined in this module--the group up here at
@@ -634,6 +635,15 @@ class LerpFunctionInterval(Interval.Interval):
         # Initialize superclass
         Interval.Interval.__init__(self, name, duration)
 
+    def _privStep(self, t):
+        profile.runctx('self._privStep(t)', globals(), locals(), 't.prof')
+        print "LerpFunctionInterval %s" % (self.function.__name__)
+        s = pstats.Stats('t.prof')
+        s.sort_stats('time')
+        #s.sort_stats('cumulative')
+        s.print_stats(5)
+        self.privStep = self._privStep
+
     def privStep(self, t):
         # Evaluate the function
         if (t >= self.duration):

+ 69 - 4
direct/src/showbase/Loader.py

@@ -21,8 +21,9 @@ class Loader(DirectObject):
     loaderIndex = 0
     
     class Callback:
-        def __init__(self, numObjects, callback, extraArgs):
+        def __init__(self, numObjects, gotList, callback, extraArgs):
             self.objects = [None] * numObjects
+            self.gotList = gotList
             self.callback = callback
             self.extraArgs = extraArgs
             self.numRemaining = numObjects
@@ -32,7 +33,10 @@ class Loader(DirectObject):
             self.numRemaining -= 1
 
             if self.numRemaining == 0:
-                self.callback(*(self.objects + self.extraArgs))
+                if self.gotList:
+                    self.callback(self.objects, *self.extraArgs)
+                else:
+                    self.callback(*(self.objects + self.extraArgs))
 
     # special methods
     def __init__(self, base):
@@ -50,6 +54,7 @@ class Loader(DirectObject):
 
     # model loading funcs
     def loadModel(self, modelPath, loaderOptions = None, noCache = None,
+                  allowInstance = False,
                   callback = None, extraArgs = []):
         """
         Attempts to load a model or models from one or more relative
@@ -101,6 +106,8 @@ class Loader(DirectObject):
                 loaderOptions.setFlags(loaderOptions.getFlags() | LoaderOptions.LFNoCache)
             else:
                 loaderOptions.setFlags(loaderOptions.getFlags() & ~LoaderOptions.LFNoCache)
+        if allowInstance:
+            loaderOptions.setFlags(loaderOptions.getFlags() | LoaderOptions.LFAllowInstance)
 
         if isinstance(modelPath, types.StringTypes) or \
            isinstance(modelPath, Filename):
@@ -136,7 +143,7 @@ class Loader(DirectObject):
             # requested models have been loaded, we'll invoke the
             # callback (passing it the models on the parameter list).
             
-            cb = Loader.Callback(len(modelList), callback, extraArgs)
+            cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
             i=0
             for modelPath in modelList:
                 request = ModelLoadRequest(Filename(modelPath), loaderOptions)
@@ -414,7 +421,7 @@ class Loader(DirectObject):
             # requested sounds have been loaded, we'll invoke the
             # callback (passing it the sounds on the parameter list).
             
-            cb = Loader.Callback(len(soundList), callback, extraArgs)
+            cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
             for i in range(len(soundList)):
                 soundPath = soundList[i]
                 request = AudioLoadRequest(manager, soundPath, positional)
@@ -441,6 +448,64 @@ class Loader(DirectObject):
         if (shaderPath != None):
             ShaderPool.releaseShader(shaderPath)
 
+    def asyncFlattenStrong(self, model, inPlace = True,
+                           callback = None, extraArgs = []):
+        """ Performs a model.flattenStrong() operation in a sub-thread
+        (if threading is compiled into Panda).  The model may be a
+        single NodePath, or it may be a list of NodePaths.
+
+        Each model is duplicated and flattened in the sub-thread.
+
+        If inPlace is True, then when the flatten operation completes,
+        the newly flattened copies are automatically dropped into the
+        scene graph, in place the original models.
+
+        If a callback is specified, then it is called after the
+        operation is finished, receiving the flattened model (or a
+        list of flattened models)."""
+        
+        if isinstance(model, NodePath):
+            # We were given a single model.
+            modelList = [model]
+            gotList = False
+        else:
+            # Assume we were given a list of models.
+            modelList = model
+            gotList = True
+
+        if inPlace:
+            extraArgs = [gotList, callback, modelList, extraArgs]
+            callback = self.__asyncFlattenDone
+            gotList = True
+
+        cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
+        i=0
+        for model in modelList:
+            request = ModelFlattenRequest(model.node())
+            request.setDoneEvent(self.hook)
+            request.setPythonObject((cb, i))
+            i+=1
+            self.loader.loadAsync(request)
+
+    def __asyncFlattenDone(self, models, 
+                           gotList, callback, origModelList, extraArgs):
+        """ The asynchronous flatten operation has completed; quietly
+        drop in the new models. """
+        print "asyncFlattenDone: %s" % (models,)
+        assert(len(models) == len(origModelList))
+        for i in range(len(models)):
+            origModelList[i].getChildren().detach()
+            orig = origModelList[i].node()
+            flat = models[i].node()
+            orig.copyAllProperties(flat)
+            orig.replaceNode(flat)
+
+        if callback:
+            if gotList:
+                callback(origModelList, *extraArgs)
+            else:
+                callback(*(origModelList + extraArgs))
+
     def __gotAsyncObject(self, request):
         """A model or sound file or some such thing has just been
         loaded asynchronously by the sub-thread.  Add it to the list