Bläddra i källkod

Merge branch 'master' of https://github.com/panda3d/panda3d

David Rose 10 år sedan
förälder
incheckning
439ee70845
100 ändrade filer med 619 tillägg och 1276 borttagningar
  1. 1 1
      .travis.yml
  2. 6 1
      contrib/.gitignore
  3. 1 0
      direct/.gitignore
  4. 2 3
      direct/src/actor/Actor.py
  5. 1 1
      direct/src/cluster/ClusterClient.py
  6. 0 1
      direct/src/cluster/ClusterConfig.py
  7. 1 1
      direct/src/cluster/ClusterMsgs.py
  8. 1 1
      direct/src/cluster/ClusterServer.py
  9. 3 7
      direct/src/controls/GravityWalker.py
  10. 3 1
      direct/src/dcparser/dcPython.h
  11. 3 3
      direct/src/directbase/TestStart.py
  12. 1 1
      direct/src/directbase/ppython.cxx
  13. 2 16
      direct/src/directdevices/DirectDeviceManager.py
  14. 0 1
      direct/src/directnotify/Logger.py
  15. 1 2
      direct/src/directnotify/Notifier.py
  16. 0 44
      direct/src/directscripts/cleancvstree
  17. 1 1
      direct/src/directscripts/doxygen_filter.py
  18. 1 1
      direct/src/directscripts/extract_docs.py
  19. 0 124
      direct/src/directscripts/make-panda3d-tgz.py
  20. 1 1
      direct/src/directtools/DirectCameraControl.py
  21. 1 1
      direct/src/directtools/DirectGeometry.py
  22. 1 1
      direct/src/directtools/DirectGlobals.py
  23. 1 1
      direct/src/directtools/DirectGrid.py
  24. 1 1
      direct/src/directtools/DirectLights.py
  25. 7 9
      direct/src/directtools/DirectSession.py
  26. 0 1
      direct/src/distributed/GridChild.py
  27. 2 1
      direct/src/distributed/PyDatagram.py
  28. 2 1
      direct/src/distributed/PyDatagramIterator.py
  29. 5 4
      direct/src/extensions_native/CInterval_extensions.py
  30. 47 742
      direct/src/extensions_native/NodePath_extensions.py
  31. 1 1
      direct/src/extensions_native/VBase3_extensions.py
  32. 1 1
      direct/src/extensions_native/VBase4_extensions.py
  33. 28 0
      direct/src/extensions_native/core_extensions.py
  34. 2 4
      direct/src/ffi/DoGenPyCode.py
  35. 0 1
      direct/src/ffi/FFITypes.py
  36. 0 1
      direct/src/ffi/jGenPyCode.py
  37. 2 2
      direct/src/filter/CommonFilters.py
  38. 3 4
      direct/src/filter/FilterManager.py
  39. 0 1
      direct/src/fsm/FourState.py
  40. 0 1
      direct/src/fsm/SampleFSM.py
  41. 0 1
      direct/src/fsm/State.py
  42. 1 1
      direct/src/fsm/StatePush.py
  43. 1 1
      direct/src/gui/DirectButton.py
  44. 1 1
      direct/src/gui/DirectCheckBox.py
  45. 1 2
      direct/src/gui/DirectCheckButton.py
  46. 1 1
      direct/src/gui/DirectDialog.py
  47. 1 1
      direct/src/gui/DirectEntry.py
  48. 2 4
      direct/src/gui/DirectEntryScroll.py
  49. 2 2
      direct/src/gui/DirectFrame.py
  50. 7 9
      direct/src/gui/DirectGuiBase.py
  51. 1 1
      direct/src/gui/DirectGuiGlobals.py
  52. 3 1
      direct/src/gui/DirectGuiTest.py
  53. 1 2
      direct/src/gui/DirectLabel.py
  54. 1 1
      direct/src/gui/DirectOptionMenu.py
  55. 1 1
      direct/src/gui/DirectRadioButton.py
  56. 1 1
      direct/src/gui/DirectScrollBar.py
  57. 1 1
      direct/src/gui/DirectScrolledFrame.py
  58. 2 2
      direct/src/gui/DirectScrolledList.py
  59. 1 1
      direct/src/gui/DirectSlider.py
  60. 1 1
      direct/src/gui/DirectWaitBar.py
  61. 2 3
      direct/src/gui/OnscreenGeom.py
  62. 2 3
      direct/src/gui/OnscreenImage.py
  63. 2 2
      direct/src/gui/OnscreenText.py
  64. 2 1
      direct/src/interval/ActorInterval.py
  65. 2 1
      direct/src/interval/AnimControlInterval.py
  66. 2 2
      direct/src/interval/FunctionInterval.py
  67. 2 1
      direct/src/interval/IndirectInterval.py
  68. 2 3
      direct/src/interval/Interval.py
  69. 10 8
      direct/src/interval/IntervalGlobal.py
  70. 2 4
      direct/src/interval/IntervalManager.py
  71. 5 3
      direct/src/interval/IntervalTest.py
  72. 2 1
      direct/src/interval/LerpInterval.py
  73. 5 4
      direct/src/interval/MetaInterval.py
  74. 2 1
      direct/src/interval/MopathInterval.py
  75. 2 2
      direct/src/interval/ParticleInterval.py
  76. 2 2
      direct/src/interval/ProjectileInterval.py
  77. 2 2
      direct/src/interval/ProjectileIntervalTest.py
  78. 2 1
      direct/src/interval/SoundInterval.py
  79. 2 2
      direct/src/interval/TestInterval.py
  80. 2 1
      direct/src/motiontrail/MotionTrail.py
  81. 16 27
      direct/src/p3d/AppRunner.py
  82. 2 0
      direct/src/p3d/DWBPackageInstaller.py
  83. 137 62
      direct/src/p3d/DeploymentTools.py
  84. 2 0
      direct/src/p3d/FileSpec.py
  85. 19 21
      direct/src/p3d/HostInfo.py
  86. 2 0
      direct/src/p3d/InstalledHostData.py
  87. 2 0
      direct/src/p3d/InstalledPackageData.py
  88. 2 0
      direct/src/p3d/JavaScript.py
  89. 7 4
      direct/src/p3d/PackageInfo.py
  90. 2 0
      direct/src/p3d/PackageInstaller.py
  91. 2 1
      direct/src/p3d/PackageMerger.py
  92. 150 65
      direct/src/p3d/Packager.py
  93. 2 0
      direct/src/p3d/PatchMaker.py
  94. 2 0
      direct/src/p3d/ScanDirectoryNode.py
  95. 2 0
      direct/src/p3d/SeqValue.py
  96. 1 1
      direct/src/p3d/coreapi.pdef
  97. 20 9
      direct/src/p3d/packp3d.py
  98. 12 4
      direct/src/p3d/panda3d.pdef
  99. 17 8
      direct/src/p3d/ppackage.py
  100. 3 3
      direct/src/p3d/thirdparty.pdef

+ 1 - 1
.travis.yml

@@ -4,7 +4,7 @@ compiler:
   - clang
   - clang
 before_script:
 before_script:
   - sudo apt-get install python-dev libpng-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libjpeg-dev libopenal-dev libode-dev nvidia-cg-toolkit
   - sudo apt-get install python-dev libpng-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libjpeg-dev libopenal-dev libode-dev nvidia-cg-toolkit
-script: python makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT --installer
+script: python makepanda/makepanda.py --everything --verbose --git-commit $TRAVIS_COMMIT --installer --threads 2
 notifications:
 notifications:
   irc:
   irc:
     channels:
     channels:

+ 6 - 1
contrib/.gitignore

@@ -1,4 +1,9 @@
+*.pyc
+*.pyo
 /__init__.py
 /__init__.py
-/built/
+# These are files that are generated within the source tree by the
+# ppremake system.
 Makefile
 Makefile
 pp.dep
 pp.dep
+/built/
+Opt?-*

+ 1 - 0
direct/.gitignore

@@ -1,4 +1,5 @@
 *.pyc
 *.pyc
+*.pyo
 /__init__.py
 /__init__.py
 # These are files that are generated within the source tree by the
 # These are files that are generated within the source tree by the
 # ppremake system.
 # ppremake system.

+ 2 - 3
direct/src/actor/Actor.py

@@ -2,11 +2,10 @@
 
 
 __all__ = ['Actor']
 __all__ = ['Actor']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-from pandac.PandaModules import LODNode
-import types, copy
+import types
 
 
 class Actor(DirectObject, NodePath):
 class Actor(DirectObject, NodePath):
     """
     """

+ 1 - 1
direct/src/cluster/ClusterClient.py

@@ -1,6 +1,6 @@
 """ClusterClient: Master for mutli-piping or PC clusters.  """
 """ClusterClient: Master for mutli-piping or PC clusters.  """
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from ClusterMsgs import *
 from ClusterMsgs import *
 from ClusterConfig import *
 from ClusterConfig import *
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

+ 0 - 1
direct/src/cluster/ClusterConfig.py

@@ -1,6 +1,5 @@
 
 
 from ClusterClient import *
 from ClusterClient import *
-import string
 
 
 # A dictionary of information for various cluster configurations.
 # A dictionary of information for various cluster configurations.
 # Dictionary is keyed on cluster-config string
 # Dictionary is keyed on cluster-config string

+ 1 - 1
direct/src/cluster/ClusterMsgs.py

@@ -3,7 +3,7 @@
 # This module is intended to supply routines and dataformats common to
 # This module is intended to supply routines and dataformats common to
 # both ClusterClient and ClusterServer.
 # both ClusterClient and ClusterServer.
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.distributed.PyDatagram import PyDatagram
 from direct.distributed.PyDatagram import PyDatagram
 from direct.distributed.PyDatagramIterator import PyDatagramIterator
 from direct.distributed.PyDatagramIterator import PyDatagramIterator
 import time
 import time

+ 1 - 1
direct/src/cluster/ClusterServer.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import *
+from panda3d.core import *
 from ClusterMsgs import *
 from ClusterMsgs import *
 from direct.distributed.MsgTypes import *
 from direct.distributed.MsgTypes import *
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

+ 3 - 7
direct/src/controls/GravityWalker.py

@@ -179,9 +179,9 @@ class GravityWalker(DirectObject.DirectObject):
         # a higher or lower value depending on whether you want an avatar
         # a higher or lower value depending on whether you want an avatar
         # that is outside of the world to step up to the floor when they
         # that is outside of the world to step up to the floor when they
         # get under valid floor:
         # get under valid floor:
-        cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0)
+        self.cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0)
         cRayNode = CollisionNode('GW.cRayNode')
         cRayNode = CollisionNode('GW.cRayNode')
-        cRayNode.addSolid(cRay)
+        cRayNode.addSolid(self.cRay)
         self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
         self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
         cRayNode.setFromCollideMask(bitmask)
         cRayNode.setFromCollideMask(bitmask)
         cRayNode.setIntoCollideMask(BitMask32.allOff())
         cRayNode.setIntoCollideMask(BitMask32.allOff())
@@ -697,8 +697,4 @@ class GravityWalker(DirectObject.DirectObject):
     # There are sometimes issues if the collision ray height is
     # There are sometimes issues if the collision ray height is
     # so tall that it collides with multiple levels of floors.
     # so tall that it collides with multiple levels of floors.
     def setCollisionRayHeight(self, height):
     def setCollisionRayHeight(self, height):
-        oldNode = self.avatarNodePath.getNode(0)
-        cRayNode = oldNode.getChild(2)
-        cRayNode.removeSolid(0)
-        cRay = CollisionRay(0.0, 0.0, height, 0.0, 0.0, -1.0)
-        cRayNode.addSolid(cRay)        
+        self.cRay.setOrigin(0.0, 0.0, height)

+ 3 - 1
direct/src/dcparser/dcPython.h

@@ -20,8 +20,10 @@
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
 
 
-#undef HAVE_LONG_LONG  // NSPR and Python both define this.
+#define PY_SSIZE_T_CLEAN 1
+
 #undef _POSIX_C_SOURCE
 #undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
 #include <Python.h>
 #include <Python.h>
 
 
 // Python 2.5 adds Py_ssize_t; earlier versions don't have it.
 // Python 2.5 adds Py_ssize_t; earlier versions don't have it.

+ 3 - 3
direct/src/directbase/TestStart.py

@@ -1,10 +1,10 @@
-print 'TestStart: Starting up test environment.'
+print('TestStart: Starting up test environment.')
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 from direct.showbase.PythonUtil import *
 from direct.showbase.PythonUtil import *
 from direct.showbase import ShowBase
 from direct.showbase import ShowBase
-ShowBase.ShowBase()
+base = ShowBase.ShowBase()
 
 
 # Put an axis in the world:
 # Put an axis in the world:
 loader.loadModel("models/misc/xyzAxis").reparentTo(render)
 loader.loadModel("models/misc/xyzAxis").reparentTo(render)

+ 1 - 1
direct/src/directbase/ppython.cxx

@@ -36,7 +36,7 @@ int main(int argc, char *mb_argv[]) {
     size_t len = mbstowcs(NULL, mb_argv[i], 0);
     size_t len = mbstowcs(NULL, mb_argv[i], 0);
     argv[i] = new wchar_t[len + 1];
     argv[i] = new wchar_t[len + 1];
     mbstowcs(argv[i], mb_argv[i], len);
     mbstowcs(argv[i], mb_argv[i], len);
-    argv[i][len] = NULL;
+    argv[i][len] = 0;
   }
   }
   // Just for good measure
   // Just for good measure
   argv[argc] = NULL;
   argv[argc] = NULL;

+ 2 - 16
direct/src/directdevices/DirectDeviceManager.py

@@ -1,7 +1,8 @@
 """ Class used to create and control vrpn devices """
 """ Class used to create and control vrpn devices """
 
 
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.vrpn import *
 
 
 ANALOG_MIN = -0.95
 ANALOG_MIN = -0.95
 ANALOG_MAX = 0.95
 ANALOG_MAX = 0.95
@@ -294,18 +295,3 @@ class DirectTimecodeReader(AnalogNode, DirectObject):
     def __repr__(self):
     def __repr__(self):
         str = ('%s: %d:%d:%d:%d' % ((self.name,) + self.getTime()[:-1]))
         str = ('%s: %d:%d:%d:%d' % ((self.name,) + self.getTime()[:-1]))
         return str
         return str
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+ 0 - 1
direct/src/directnotify/Logger.py

@@ -1,7 +1,6 @@
 """Logger module: contains the logger class which creates and writes
 """Logger module: contains the logger class which creates and writes
    data to log files on disk"""
    data to log files on disk"""
 
 
-import sys
 import time
 import time
 import math
 import math
 
 

+ 1 - 2
direct/src/directnotify/Notifier.py

@@ -6,7 +6,6 @@ from LoggerGlobal import defaultLogger
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
 from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
 from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
 import time
 import time
-import types
 import sys
 import sys
 
 
 class Notifier:
 class Notifier:
@@ -236,7 +235,7 @@ class Notifier:
         Prints the string to output followed by a newline.
         Prints the string to output followed by a newline.
         """
         """
         if self.streamWriter:
         if self.streamWriter:
-            self.streamWriter.appendData(string + '\n')
+            self.streamWriter.write(string + '\n')
         else:
         else:
             print >> sys.stderr, string
             print >> sys.stderr, string
 
 

+ 0 - 44
direct/src/directscripts/cleancvstree

@@ -1,44 +0,0 @@
-##############################################################################
-#
-# cleancvstree
-#
-# Cleancvstree searches a CVS tree for files that are not in CVS, and
-# deletes them.  Be careful using it --- it's very aggressive.
-#
-##############################################################################
-
-import sys,os
-
-def cleanCvsTree(dir):
-    try:
-        sub = os.listdir(dir)
-    except:
-	print "Could not read directory: "+dir
-	return
-    valid = {}
-    try:
-	readentries = 0
-        cvsent = open(dir + "/CVS/Entries")
-        for line in cvsent:
-            words = line.split("/")
-            if (len(words) > 1):
-                valid[words[1]] = 1
-        cvsent.close()
-	readentries = 1
-    except:
-	print "Could not read "+dir+"/CVS/Entries"
-    if (readentries):
-	for file in sub:
-	    if (os.path.isfile(dir+"/"+file)):
-                if (valid.has_key(file)==0):
-		    os.unlink(dir+"/"+file)
-    for file in sub:
-	if (file != "CVS"):
-            if (os.path.isdir(dir+"/"+file)):
-                cleanCvsTree(dir+"/"+file)
-
-if (os.path.isdir(sys.argv[1])==0):
-    print "Not a directory: "+sys.argv[1]
-    os.exit(1)
-
-cleanCvsTree(sys.argv[1])

+ 1 - 1
direct/src/directscripts/doxygen_filter.py

@@ -2,7 +2,7 @@
 doxygen can understand and process.  It can be used
 doxygen can understand and process.  It can be used
 as an INPUT_FILTER in doxygen. """
 as an INPUT_FILTER in doxygen. """
 
 
-import sys, re, os
+import sys, os
 
 
 # Explicitly include these files.  Besides these, all
 # Explicitly include these files.  Besides these, all
 # files ending in _src will be explicitly included too.
 # files ending in _src will be explicitly included too.

+ 1 - 1
direct/src/directscripts/extract_docs.py

@@ -7,7 +7,7 @@ files in the lib/pandac/input directory. """
 
 
 __all__ = []
 __all__ = []
 
 
-import os, re
+import os
 import panda3d, pandac
 import panda3d, pandac
 from panda3d.dtoolconfig import *
 from panda3d.dtoolconfig import *
 
 

+ 0 - 124
direct/src/directscripts/make-panda3d-tgz.py

@@ -1,124 +0,0 @@
-#!/usr/bin/env python
-
-"""This script generates the panda3d-date.tar.gz tarball for a file
-release of panda3d onto the SourceForge download site.
-
-Options:
-
-    -d cvsroot
-        Specifies the CVSROOT string to use to tag and export the
-        tree.  The default is $SFROOT if it is defined, or $CVSROOT
-        otherwise.
-
-    -r tag
-        Specifies the tag to export from.  If this parameter is
-        specified, the tree is not tagged again; otherwise, the
-        current head of the CVS tree is tagged with the file version
-        name.
-
-    -m module
-        Specifies the module to check out and build.  The default is
-        panda3d.
-"""
-
-import sys
-import os
-import os.path
-import getopt
-import time
-import glob
-import shutil
-
-CVSROOT = os.getenv('SFROOT') or os.getenv('CVSROOT')
-ORIGTAG = ''
-MODULE  = 'panda3d'
-
-def usage(code, msg = ''):
-    print >> sys.stderr, __doc__
-    print >> sys.stderr, msg
-    sys.exit(code)
-
-try:
-    opts, args = getopt.getopt(sys.argv[1:], 'd:r:m:h')
-except getopt.error, msg:
-    usage(1, msg)
-
-for opt, arg in opts:
-    if opt == '-d':
-        CVSROOT = arg
-    elif opt == '-r':
-        ORIGTAG = arg
-    elif opt == '-m':
-        MODULE = arg
-    elif opt == '-h':
-        usage(0)
-
-if not CVSROOT:
-    usage(1, 'CVSROOT must have a value.')
-
-if not MODULE:
-    usage(1, 'MODULE must have a value.')
-
-basename = MODULE + '-' + time.strftime("%Y-%m-%d")
-tarfile = basename + '.tar.gz'
-zipfile = basename + '.zip'
-
-if os.path.exists(basename):
-    print basename, 'already exists in the local directory!'
-    sys.exit(1)
-
-if not ORIGTAG:
-    # If we weren't given a starting tag, make one.
-    tag = basename
-
-    print 'Tagging sources.'
-    cmd = 'cvs -f -d "%s" rtag -F -r HEAD "%s" "%s"' % (CVSROOT, tag, MODULE)
-    if os.system(cmd) != 0:
-        sys.exit(1)
-else:
-    # Otherwise, we were given a starting tag, so use it.
-    tag = ORIGTAG
-
-print 'Checking out "%s" as "%s".' % (MODULE, basename)
-cmd = 'cvs -z3 -f -d "%s" export -r "%s" -d "%s" "%s"' % (CVSROOT, tag,
-                                                          basename, MODULE)
-if os.system(cmd) != 0:
-    sys.exit(1)
-
-# Move the contents of the doc module into the root directory where people
-# will expect to see it.
-docdir = basename + os.sep + 'doc'
-if os.path.exists(docdir):
-    files = glob.glob(docdir + os.sep + '*')
-    for file in files:
-        shutil.copy(file, basename)
-        os.remove(file)
-    os.rmdir(docdir)
-
-# Generate the autoconf scripts for ppremake.
-if MODULE == 'ppremake':
-    ppremakedir = basename
-else:
-    ppremakedir = basename + os.sep + 'ppremake'
-if os.path.exists(ppremakedir):
-    cmd = 'cd "./%s" && aclocal && autoheader && automake --foreign -a && autoconf' % (ppremakedir)
-    if os.system(cmd) != 0:
-        sys.exit(1)
-
-# Generate the tarball.
-print 'Generating %s' % (tarfile)
-if os.path.exists(tarfile):
-    os.remove(tarfile)
-cmd = 'tar cf - "%s" | gzip -9 > "%s"' % (basename, tarfile)
-if os.system(cmd) != 0:
-    sys.exit(1)
-
-# Also generate a zip file.
-print 'Generating %s' % (zipfile)
-if os.path.exists(zipfile):
-    os.remove(zipfile)
-cmd = 'zip -9rq "%s" "%s"' % (zipfile, basename)
-if os.system(cmd) != 0:
-    sys.exit(1)
-
-shutil.rmtree(basename)

+ 1 - 1
direct/src/directtools/DirectCameraControl.py

@@ -222,7 +222,7 @@ class DirectCameraControl(DirectObject):
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
             self.computeCOA(base.direct.iRay.pickGeom(skipFlags = skipFlags))
             self.computeCOA(base.direct.iRay.pickGeom(skipFlags = skipFlags))
             # Record reference point
             # Record reference point
-            self.coaMarkerRef.iPosHprScale(base.cam)
+            self.coaMarkerRef.setPosHprScale(base.cam, 0, 0, 0, 0, 0, 0, 1, 1, 1)
             # Record entries
             # Record entries
             self.cqEntries = []
             self.cqEntries = []
             for i in range(base.direct.iRay.getNumEntries()):
             for i in range(base.direct.iRay.getNumEntries()):

+ 1 - 1
direct/src/directtools/DirectGeometry.py

@@ -1,5 +1,5 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from DirectGlobals import *
 from DirectGlobals import *
 from DirectUtil import *
 from DirectUtil import *
 import math
 import math

+ 1 - 1
direct/src/directtools/DirectGlobals.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import Vec3, Point3, BitMask32
+from panda3d.core import Vec3, Point3, BitMask32
 
 
 UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
 UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
               'GridBack', 'unpickable']
               'GridBack', 'unpickable']

+ 1 - 1
direct/src/directtools/DirectGrid.py

@@ -1,5 +1,5 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from DirectUtil import *
 from DirectUtil import *
 from DirectGeometry import *
 from DirectGeometry import *

+ 1 - 1
direct/src/directtools/DirectLights.py

@@ -1,5 +1,5 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from string import lower
 from string import lower
 
 
 class DirectLight(NodePath):
 class DirectLight(NodePath):

+ 7 - 9
direct/src/directtools/DirectSession.py

@@ -2,7 +2,7 @@ import math
 import types
 import types
 import string
 import string
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from DirectUtil import *
 from DirectUtil import *
 
 
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
@@ -304,6 +304,7 @@ class DirectSession(DirectObject):
         except NameError:
         except NameError:
             # Has the clusterMode been set via a config variable?
             # Has the clusterMode been set via a config variable?
             self.clusterMode = base.config.GetString("cluster-mode", '')
             self.clusterMode = base.config.GetString("cluster-mode", '')
+
         if self.clusterMode == 'client':
         if self.clusterMode == 'client':
             self.cluster = createClusterClient()
             self.cluster = createClusterClient()
         elif self.clusterMode == 'server':
         elif self.clusterMode == 'server':
@@ -400,7 +401,7 @@ class DirectSession(DirectObject):
 
 
         if self.oobeMode:
         if self.oobeMode:
             # Position a target point to lerp the oobe camera to
             # Position a target point to lerp the oobe camera to
-            base.direct.cameraControl.camManipRef.iPosHpr(self.trueCamera)
+            base.direct.cameraControl.camManipRef.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
             ival = self.oobeCamera.posHprInterval(
             ival = self.oobeCamera.posHprInterval(
                 2.0, pos = Point3(0), hpr = Vec3(0), 
                 2.0, pos = Point3(0), hpr = Vec3(0), 
                 other = base.direct.cameraControl.camManipRef,
                 other = base.direct.cameraControl.camManipRef,
@@ -416,7 +417,7 @@ class DirectSession(DirectObject):
             cameraParent = self.camera.getParent()
             cameraParent = self.camera.getParent()
             # Prepare oobe camera
             # Prepare oobe camera
             self.oobeCamera.reparentTo(cameraParent)
             self.oobeCamera.reparentTo(cameraParent)
-            self.oobeCamera.iPosHpr(self.trueCamera)
+            self.oobeCamera.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
             # Put camera under new oobe camera
             # Put camera under new oobe camera
             self.cam.reparentTo(self.oobeCamera)
             self.cam.reparentTo(self.oobeCamera)
             # Position a target point to lerp the oobe camera to
             # Position a target point to lerp the oobe camera to
@@ -432,13 +433,13 @@ class DirectSession(DirectObject):
 
 
     def beginOOBE(self):
     def beginOOBE(self):
         # Make sure we've reached our final destination
         # Make sure we've reached our final destination
-        self.oobeCamera.iPosHpr(base.direct.cameraControl.camManipRef)
+        self.oobeCamera.setPosHpr(base.direct.cameraControl.camManipRef, 0, 0, 0, 0, 0, 0)
         base.direct.camera = self.oobeCamera
         base.direct.camera = self.oobeCamera
         self.oobeMode = 1
         self.oobeMode = 1
 
 
     def endOOBE(self):
     def endOOBE(self):
         # Make sure we've reached our final destination
         # Make sure we've reached our final destination
-        self.oobeCamera.iPosHpr(self.trueCamera)
+        self.oobeCamera.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
         # Disable OOBE mode.
         # Disable OOBE mode.
         self.cam.reparentTo(self.trueCamera)
         self.cam.reparentTo(self.trueCamera)
         base.direct.camera = self.trueCamera
         base.direct.camera = self.trueCamera
@@ -806,7 +807,7 @@ class DirectSession(DirectObject):
                            [nodePath, oldParent, self.activeParent, fWrt])
                            [nodePath, oldParent, self.activeParent, fWrt])
 
 
     def isNotCycle(self, nodePath, parent):
     def isNotCycle(self, nodePath, parent):
-        if nodePath.id() == parent.id():
+        if nodePath == parent:
             print 'DIRECT.reparent: Invalid parent'
             print 'DIRECT.reparent: Invalid parent'
             return 0
             return 0
         elif parent.hasParent():
         elif parent.hasParent():
@@ -1308,6 +1309,3 @@ class DisplayRegionList(DirectObject):
             if drc.cam == cam:
             if drc.cam == cam:
                 self.displayRegionList.remove(drc)
                 self.displayRegionList.remove(drc)
                 break
                 break
-
-# Create one
-__builtins__['direct'] = base.direct = DirectSession()

+ 0 - 1
direct/src/distributed/GridChild.py

@@ -1,6 +1,5 @@
 from direct.distributed.DistributedSmoothNodeBase import DistributedSmoothNodeBase
 from direct.distributed.DistributedSmoothNodeBase import DistributedSmoothNodeBase
 from direct.distributed.GridParent import GridParent
 from direct.distributed.GridParent import GridParent
-from pandac.PandaModules import EmbeddedValue
 
 
 class GridChild:
 class GridChild:
     """
     """

+ 2 - 1
direct/src/distributed/PyDatagram.py

@@ -3,7 +3,8 @@
 # class variable FuncDict and so we can import DCSubatomicType at the top
 # class variable FuncDict and so we can import DCSubatomicType at the top
 # of the file rather than every time we call the putArg function.
 # of the file rather than every time we call the putArg function.
 
 
-from pandac.PandaModules import *
+from panda3d.core import Datagram
+from panda3d.direct import *
 # Import the type numbers
 # Import the type numbers
 
 
 #from otp.ai.AIMsgTypes import *
 #from otp.ai.AIMsgTypes import *

+ 2 - 1
direct/src/distributed/PyDatagramIterator.py

@@ -3,7 +3,8 @@
 # class variable FuncDict and so we can import DCSubatomicType at the top
 # class variable FuncDict and so we can import DCSubatomicType at the top
 # of the file rather than every time we call the putArg function.
 # of the file rather than every time we call the putArg function.
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 # Import the type numbers
 # Import the type numbers
 
 
 class PyDatagramIterator(DatagramIterator):
 class PyDatagramIterator(DatagramIterator):

+ 5 - 4
direct/src/extensions_native/CInterval_extensions.py

@@ -1,7 +1,8 @@
+from .core import Dtool_funcToMethod
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
-notify = directNotify.newCategory("Interval")
-Dtool_ObjectToDict(CInterval,"notify", notify)
-del notify
+
+CInterval.DtoolClassDict["notify"] = directNotify.newCategory("Interval")
+
 #####################################################################
 #####################################################################
 def setT(self, t):
 def setT(self, t):
     # Overridden from the C++ function to call privPostEvent
     # Overridden from the C++ function to call privPostEvent
@@ -10,7 +11,7 @@ def setT(self, t):
     self.setT_Old(t)
     self.setT_Old(t)
     self.privPostEvent()
     self.privPostEvent()
 
 
-Dtool_ObjectToDict(CInterval, "setT_Old", CInterval.setT)
+CInterval.DtoolClassDict["setT_Old"] = CInterval.setT
 Dtool_funcToMethod(setT, CInterval)
 Dtool_funcToMethod(setT, CInterval)
 del setT
 del setT
 #####################################################################
 #####################################################################

+ 47 - 742
direct/src/extensions_native/NodePath_extensions.py

@@ -10,22 +10,16 @@ of the NodePath class
 
 
 ####################################################################
 ####################################################################
 def id(self):
 def id(self):
-        """Returns a unique id identifying the NodePath instance"""
-        print "Warning: NodePath.id() is deprecated.  Use hash(NodePath) or NodePath.get_key() instead."
+        """Deprecated.  Returns a unique id identifying the NodePath instance"""
+        print("Warning: NodePath.id() is deprecated.  Use hash(NodePath) or NodePath.get_key() instead.")
         return self.getKey()
         return self.getKey()
 
 
 Dtool_funcToMethod(id, NodePath)
 Dtool_funcToMethod(id, NodePath)
 del id
 del id
 #####################################################################
 #####################################################################
-
-##    def __hash__(self):  // inside c code
-##        return self.getKey()
-#####################################################################
-
-    # For iterating over children
 def getChildrenAsList(self):
 def getChildrenAsList(self):
-        """Converts a node path's child NodePathCollection into a list"""
-        print "Warning: NodePath.getChildrenAsList() is deprecated.  Use get_children() instead."
+        """Deprecated.  Converts a node path's child NodePathCollection into a list"""
+        print("Warning: NodePath.getChildrenAsList() is deprecated.  Use get_children() instead.")
         return list(self.getChildren())
         return list(self.getChildren())
 
 
 Dtool_funcToMethod(getChildrenAsList, NodePath)
 Dtool_funcToMethod(getChildrenAsList, NodePath)
@@ -35,7 +29,7 @@ del getChildrenAsList
 def printChildren(self):
 def printChildren(self):
         """Prints out the children of the bottom node of a node path"""
         """Prints out the children of the bottom node of a node path"""
         for child in self.getChildren():
         for child in self.getChildren():
-            print child.getName()
+            print(child.getName())
 Dtool_funcToMethod(printChildren, NodePath)
 Dtool_funcToMethod(printChildren, NodePath)
 del printChildren
 del printChildren
 #####################################################################
 #####################################################################
@@ -95,8 +89,8 @@ del isolate
 #####################################################################
 #####################################################################
 
 
 def remove(self):
 def remove(self):
-        """Remove a node path from the scene graph"""
-        print "Warning: NodePath.remove() is deprecated.  Use remove_node() instead."
+        """Deprecated.  Remove a node path from the scene graph"""
+        print("Warning: NodePath.remove() is deprecated.  Use remove_node() instead.")
         # Send message in case anyone needs to do something
         # Send message in case anyone needs to do something
         # before node is deleted
         # before node is deleted
         messenger.send('preRemoveNodePath', [self])
         messenger.send('preRemoveNodePath', [self])
@@ -109,11 +103,11 @@ del remove
 def lsNames(self):
 def lsNames(self):
         """Walk down a tree and print out the path"""
         """Walk down a tree and print out the path"""
         if self.isEmpty():
         if self.isEmpty():
-            print "(empty)"
+            print("(empty)")
         else:
         else:
             type = self.node().getType().getName()
             type = self.node().getType().getName()
             name = self.getName()
             name = self.getName()
-            print type + "  " + name
+            print(type + "  " + name)
             self.lsNamesRecurse()
             self.lsNamesRecurse()
 
 
 Dtool_funcToMethod(lsNames, NodePath)
 Dtool_funcToMethod(lsNames, NodePath)
@@ -124,7 +118,7 @@ def lsNamesRecurse(self, indentString=' '):
         for nodePath in self.getChildren():
         for nodePath in self.getChildren():
             type = nodePath.node().getType().getName()
             type = nodePath.node().getType().getName()
             name = nodePath.getName()
             name = nodePath.getName()
-            print indentString + type + "  " + name
+            print(indentString + type + "  " + name)
             nodePath.lsNamesRecurse(indentString + " ")
             nodePath.lsNamesRecurse(indentString + " ")
 
 
 Dtool_funcToMethod(lsNamesRecurse, NodePath)
 Dtool_funcToMethod(lsNamesRecurse, NodePath)
@@ -138,7 +132,7 @@ def reverseLsNames(self):
         for nodePath in ancestry:
         for nodePath in ancestry:
             type = nodePath.node().getType().getName()
             type = nodePath.node().getType().getName()
             name = nodePath.getName()
             name = nodePath.getName()
-            print indentString + type + "  " + name
+            print(indentString + type + "  " + name)
             indentString = indentString + " "
             indentString = indentString + " "
 
 
 Dtool_funcToMethod(reverseLsNames, NodePath)
 Dtool_funcToMethod(reverseLsNames, NodePath)
@@ -146,7 +140,7 @@ del reverseLsNames
 #####################################################################
 #####################################################################
 def getAncestry(self):
 def getAncestry(self):
         """Get a list of a node path's ancestors"""
         """Get a list of a node path's ancestors"""
-        print "NodePath.getAncestry() is deprecated.  Use get_ancestors() instead."""
+        print("NodePath.getAncestry() is deprecated.  Use get_ancestors() instead.""")
         ancestors = list(self.getAncestors())
         ancestors = list(self.getAncestors())
         ancestors.reverse()
         ancestors.reverse()
         return ancestors
         return ancestors
@@ -197,11 +191,11 @@ def printPos(self, other = None, sd = 2):
         else:
         else:
             pos = self.getPos()
             pos = self.getPos()
             otherString = ''
             otherString = ''
-        print (self.getName() + '.setPos(' + otherString +
+        print((self.getName() + '.setPos(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] +
                formatString % pos[2] +
-               ')\n')
+               ')\n'))
 Dtool_funcToMethod(printPos, NodePath)
 Dtool_funcToMethod(printPos, NodePath)
 del printPos
 del printPos
 #####################################################################
 #####################################################################
@@ -215,11 +209,11 @@ def printHpr(self, other = None, sd = 2):
         else:
         else:
             hpr = self.getHpr()
             hpr = self.getHpr()
             otherString = ''
             otherString = ''
-        print (self.getName() + '.setHpr(' + otherString +
+        print((self.getName() + '.setHpr(' + otherString +
                formatString % hpr[0] + ', ' +
                formatString % hpr[0] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[2] +
                formatString % hpr[2] +
-               ')\n')
+               ')\n'))
 Dtool_funcToMethod(printHpr, NodePath)
 Dtool_funcToMethod(printHpr, NodePath)
 del printHpr
 del printHpr
 #####################################################################
 #####################################################################
@@ -233,11 +227,11 @@ def printScale(self, other = None, sd = 2):
         else:
         else:
             scale = self.getScale()
             scale = self.getScale()
             otherString = ''
             otherString = ''
-        print (self.getName() + '.setScale(' + otherString +
+        print((self.getName() + '.setScale(' + otherString +
                formatString % scale[0] + ', ' +
                formatString % scale[0] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[2] +
                formatString % scale[2] +
-               ')\n')
+               ')\n'))
 
 
 Dtool_funcToMethod(printScale, NodePath)
 Dtool_funcToMethod(printScale, NodePath)
 del printScale
 del printScale
@@ -253,14 +247,14 @@ def printPosHpr(self, other = None, sd = 2):
             pos = self.getPos()
             pos = self.getPos()
             hpr = self.getHpr()
             hpr = self.getHpr()
             otherString = ''
             otherString = ''
-        print (self.getName() + '.setPosHpr(' + otherString +
+        print((self.getName() + '.setPosHpr(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] + ', ' +
                formatString % pos[2] + ', ' +
                formatString % hpr[0] + ', ' +
                formatString % hpr[0] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[2] +
                formatString % hpr[2] +
-               ')\n')
+               ')\n'))
 
 
 Dtool_funcToMethod(printPosHpr, NodePath)
 Dtool_funcToMethod(printPosHpr, NodePath)
 del printPosHpr
 del printPosHpr
@@ -278,7 +272,7 @@ def printPosHprScale(self, other = None, sd = 2):
             hpr = self.getHpr()
             hpr = self.getHpr()
             scale = self.getScale()
             scale = self.getScale()
             otherString = ''
             otherString = ''
-        print (self.getName() + '.setPosHprScale(' + otherString +
+        print((self.getName() + '.setPosHprScale(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] + ', ' +
                formatString % pos[2] + ', ' +
@@ -288,14 +282,14 @@ def printPosHprScale(self, other = None, sd = 2):
                formatString % scale[0] + ', ' +
                formatString % scale[0] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[2] +
                formatString % scale[2] +
-               ')\n')
+               ')\n'))
 
 
 Dtool_funcToMethod(printPosHprScale, NodePath)
 Dtool_funcToMethod(printPosHprScale, NodePath)
 del printPosHprScale
 del printPosHprScale
 #####################################################################
 #####################################################################
 
 
 def printTransform(self, other = None, sd = 2, fRecursive = 0):
 def printTransform(self, other = None, sd = 2, fRecursive = 0):
-    from pandac.PandaModules import Vec3
+    from panda3d.core import Vec3
     fmtStr = '%%0.%df' % sd
     fmtStr = '%%0.%df' % sd
     name = self.getName()
     name = self.getName()
     if other == None:
     if other == None:
@@ -306,23 +300,23 @@ def printTransform(self, other = None, sd = 2, fRecursive = 0):
         pos = transform.getPos()
         pos = transform.getPos()
         if not pos.almostEqual(Vec3(0)):
         if not pos.almostEqual(Vec3(0)):
             outputString = '%s.setPos(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
             outputString = '%s.setPos(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
-            print outputString % (pos[0], pos[1], pos[2])
+            print(outputString % (pos[0], pos[1], pos[2]))
     if transform.hasHpr():
     if transform.hasHpr():
         hpr = transform.getHpr()
         hpr = transform.getHpr()
         if not hpr.almostEqual(Vec3(0)):
         if not hpr.almostEqual(Vec3(0)):
             outputString = '%s.setHpr(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
             outputString = '%s.setHpr(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
-            print outputString % (hpr[0], hpr[1], hpr[2])
+            print(outputString % (hpr[0], hpr[1], hpr[2]))
     if transform.hasScale():
     if transform.hasScale():
         if transform.hasUniformScale():
         if transform.hasUniformScale():
             scale = transform.getUniformScale()
             scale = transform.getUniformScale()
             if scale != 1.0:
             if scale != 1.0:
                 outputString = '%s.setScale(%s)' % (name, fmtStr)
                 outputString = '%s.setScale(%s)' % (name, fmtStr)
-                print outputString % scale
+                print(outputString % scale)
         else:
         else:
             scale = transform.getScale()
             scale = transform.getScale()
             if not scale.almostEqual(Vec3(1)):
             if not scale.almostEqual(Vec3(1)):
                 outputString = '%s.setScale(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
                 outputString = '%s.setScale(%s, %s, %s)' % (name, fmtStr, fmtStr, fmtStr)
-                print outputString % (scale[0], scale[1], scale[2])
+                print(outputString % (scale[0], scale[1], scale[2]))
     if fRecursive:
     if fRecursive:
         for child in self.getChildren():
         for child in self.getChildren():
             child.printTransform(other, sd, fRecursive)
             child.printTransform(other, sd, fRecursive)
@@ -383,700 +377,6 @@ def iPosHprScale(self, other = None):
 Dtool_funcToMethod(iPosHprScale, NodePath)
 Dtool_funcToMethod(iPosHprScale, NodePath)
 del iPosHprScale
 del iPosHprScale
 #####################################################################
 #####################################################################
-
-def __lerp(self, functorFunc, duration, blendType, taskName=None):
-        """
-        __lerp(self, functorFunc, float, string, string)
-        Basic lerp functionality used by other lerps.
-        Fire off a lerp. Make it a task if taskName given.
-        """
-        # functorFunc is a function which can be called to create a functor.
-        # functor creation is defered so initial state (sampled in functorFunc)
-        # will be appropriate for the time the lerp is spawned
-        from direct.task import Task
-        from direct.interval import LerpBlendHelpers
-        from direct.task.TaskManagerGlobal import taskMgr
-
-        # make the task function
-        def lerpTaskFunc(task):
-            from pandac.PandaModules import Lerp
-            from pandac.PandaModules import ClockObject
-            from direct.task.Task import Task, cont, done
-            if task.init == 1:
-                # make the lerp
-                functor = task.functorFunc()
-                task.lerp = Lerp(functor, task.duration, task.blendType)
-                task.init = 0
-            dt = globalClock.getDt()
-            task.lerp.setStepSize(dt)
-            task.lerp.step()
-            if (task.lerp.isDone()):
-                # Reset the init flag, in case the task gets re-used
-                task.init = 1
-                return(done)
-            else:
-                return(cont)
-
-        # make the lerp task
-        lerpTask = Task.Task(lerpTaskFunc)
-        lerpTask.init = 1
-        lerpTask.functorFunc = functorFunc
-        lerpTask.duration = duration
-        lerpTask.blendType = LerpBlendHelpers.getBlend(blendType)
-
-        if (taskName == None):
-            # don't spawn a task, return one instead
-            return lerpTask
-        else:
-            # spawn the lerp task
-            taskMgr.add(lerpTask, taskName)
-            return lerpTask
-
-Dtool_funcToMethod(__lerp, NodePath)
-del __lerp
-#####################################################################
-def __autoLerp(self, functorFunc, time, blendType, taskName):
-        """_autoLerp(self, functor, float, string, string)
-        This lerp uses C++ to handle the stepping. Bonus is
-        its more efficient, trade-off is there is less control"""
-        from pandac.PandaModules import AutonomousLerp
-        from direct.interval import LerpBlendHelpers
-        # make a lerp that lives in C++ land
-        functor = functorFunc()
-        lerp = AutonomousLerp(functor, time,
-                              LerpBlendHelpers.getBlend(blendType),
-                              base.eventHandler)
-        lerp.start()
-        return lerp
-
-Dtool_funcToMethod(__autoLerp, NodePath)
-del __autoLerp
-#####################################################################
-
-# user callable lerp methods
-def lerpColor(self, *posArgs, **keyArgs):
-        """lerpColor(self, *positionArgs, **keywordArgs)
-        determine which lerpColor* to call based on arguments
-        """
-        if (len(posArgs) == 2):
-            return apply(self.lerpColorVBase4, posArgs, keyArgs)
-        elif (len(posArgs) == 3):
-            return apply(self.lerpColorVBase4VBase4, posArgs, keyArgs)
-        elif (len(posArgs) == 5):
-            return apply(self.lerpColorRGBA, posArgs, keyArgs)
-        elif (len(posArgs) == 9):
-            return apply(self.lerpColorRGBARGBA, posArgs, keyArgs)
-        else:
-            # bad args
-            raise Exception("Error: NodePath.lerpColor: bad number of args")
-
-Dtool_funcToMethod(lerpColor, NodePath)
-del lerpColor
-#####################################################################
-
-def lerpColorRGBA(self, r, g, b, a, time,
-                      blendType="noBlend", auto=None, task=None):
-        """lerpColorRGBA(self, float, float, float, float, float,
-        string="noBlend", string=none, string=none)
-        """
-        def functorFunc(self = self, r = r, g = g, b = b, a = a):
-            from pandac.PandaModules import ColorLerpFunctor
-            # just end rgba values, use current color rgba values for start
-            startColor = self.getColor()
-            functor = ColorLerpFunctor(
-                self,
-                startColor[0], startColor[1],
-                startColor[2], startColor[3],
-                r, g, b, a)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorRGBA, NodePath)
-del lerpColorRGBA
-#####################################################################
-def lerpColorRGBARGBA(self, sr, sg, sb, sa, er, eg, eb, ea, time,
-                          blendType="noBlend", auto=None, task=None):
-        """lerpColorRGBARGBA(self, float, float, float, float, float,
-        float, float, float, float, string="noBlend", string=none, string=none)
-        """
-        def functorFunc(self = self, sr = sr, sg = sg, sb = sb, sa = sa,
-                        er = er, eg = eg, eb = eb, ea = ea):
-            from pandac.PandaModules import ColorLerpFunctor
-            # start and end rgba values
-            functor = ColorLerpFunctor(self, sr, sg, sb, sa,
-                                                        er, eg, eb, ea)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorRGBARGBA, NodePath)
-del lerpColorRGBARGBA
-#####################################################################
-def lerpColorVBase4(self, endColor, time,
-                        blendType="noBlend", auto=None, task=None):
-        """lerpColorVBase4(self, VBase4, float, string="noBlend", string=none,
-        string=none)
-        """
-        def functorFunc(self = self, endColor = endColor):
-            from pandac.PandaModules import ColorLerpFunctor
-            # just end vec4, use current color for start
-            startColor = self.getColor()
-            functor = ColorLerpFunctor(
-                self, startColor, endColor)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorVBase4, NodePath)
-del lerpColorVBase4
-#####################################################################
-def lerpColorVBase4VBase4(self, startColor, endColor, time,
-                          blendType="noBlend", auto=None, task=None):
-        """lerpColorVBase4VBase4(self, VBase4, VBase4, float, string="noBlend",
-        string=none, string=none)
-        """
-        def functorFunc(self = self, startColor = startColor,
-                        endColor = endColor):
-            from pandac.PandaModules import ColorLerpFunctor
-            # start color and end vec
-            functor = ColorLerpFunctor(
-                self, startColor, endColor)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-
-Dtool_funcToMethod(lerpColorVBase4VBase4, NodePath)
-del lerpColorVBase4VBase4
-#####################################################################
-    # user callable lerp methods
-def lerpColorScale(self, *posArgs, **keyArgs):
-        """lerpColorScale(self, *positionArgs, **keywordArgs)
-        determine which lerpColorScale* to call based on arguments
-        """
-        if (len(posArgs) == 2):
-            return apply(self.lerpColorScaleVBase4, posArgs, keyArgs)
-        elif (len(posArgs) == 3):
-            return apply(self.lerpColorScaleVBase4VBase4, posArgs, keyArgs)
-        elif (len(posArgs) == 5):
-            return apply(self.lerpColorScaleRGBA, posArgs, keyArgs)
-        elif (len(posArgs) == 9):
-            return apply(self.lerpColorScaleRGBARGBA, posArgs, keyArgs)
-        else:
-            # bad args
-            raise Exception("Error: NodePath.lerpColorScale: bad number of args")
-
-
-Dtool_funcToMethod(lerpColorScale, NodePath)
-del lerpColorScale
-#####################################################################
-def lerpColorScaleRGBA(self, r, g, b, a, time,
-                      blendType="noBlend", auto=None, task=None):
-        """lerpColorScaleRGBA(self, float, float, float, float, float,
-        string="noBlend", string=none, string=none)
-        """
-        def functorFunc(self = self, r = r, g = g, b = b, a = a):
-            from pandac.PandaModules import ColorScaleLerpFunctor
-            # just end rgba values, use current color rgba values for start
-            startColor = self.getColor()
-            functor = ColorScaleLerpFunctor(
-                self,
-                startColor[0], startColor[1],
-                startColor[2], startColor[3],
-                r, g, b, a)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorScaleRGBA, NodePath)
-del lerpColorScaleRGBA
-#####################################################################
-def lerpColorScaleRGBARGBA(self, sr, sg, sb, sa, er, eg, eb, ea, time,
-                          blendType="noBlend", auto=None, task=None):
-        """lerpColorScaleRGBARGBA(self, float, float, float, float, float,
-        float, float, float, float, string="noBlend", string=none, string=none)
-        """
-        def functorFunc(self = self, sr = sr, sg = sg, sb = sb, sa = sa,
-                        er = er, eg = eg, eb = eb, ea = ea):
-            from pandac.PandaModules import ColorScaleLerpFunctor
-            # start and end rgba values
-            functor = ColorScaleLerpFunctor(self, sr, sg, sb, sa,
-                                                        er, eg, eb, ea)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorScaleRGBARGBA, NodePath)
-del lerpColorScaleRGBARGBA
-#####################################################################
-def lerpColorScaleVBase4(self, endColor, time,
-                        blendType="noBlend", auto=None, task=None):
-        """lerpColorScaleVBase4(self, VBase4, float, string="noBlend", string=none,
-        string=none)
-        """
-        def functorFunc(self = self, endColor = endColor):
-            from pandac.PandaModules import ColorScaleLerpFunctor
-            # just end vec4, use current color for start
-            startColor = self.getColor()
-            functor = ColorScaleLerpFunctor(
-                self, startColor, endColor)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpColorScaleVBase4, NodePath)
-del lerpColorScaleVBase4
-#####################################################################
-def lerpColorScaleVBase4VBase4(self, startColor, endColor, time,
-                          blendType="noBlend", auto=None, task=None):
-        """lerpColorScaleVBase4VBase4(self, VBase4, VBase4, float, string="noBlend",
-        string=none, string=none)
-        """
-        def functorFunc(self = self, startColor = startColor,
-                        endColor = endColor):
-            from pandac.PandaModules import ColorScaleLerpFunctor
-            # start color and end vec
-            functor = ColorScaleLerpFunctor(
-                self, startColor, endColor)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-
-Dtool_funcToMethod(lerpColorScaleVBase4VBase4, NodePath)
-del lerpColorScaleVBase4VBase4
-#####################################################################
-def lerpHpr(self, *posArgs, **keyArgs):
-        """lerpHpr(self, *positionArgs, **keywordArgs)
-        Determine whether to call lerpHprHPR or lerpHprVBase3
-        based on first argument
-        """
-        # check to see if lerping with
-        # three floats or a VBase3
-        if (len(posArgs) == 4):
-            return apply(self.lerpHprHPR, posArgs, keyArgs)
-        elif(len(posArgs) == 2):
-            return apply(self.lerpHprVBase3, posArgs, keyArgs)
-        else:
-            # bad args
-            raise Exception("Error: NodePath.lerpHpr: bad number of args")
-
-Dtool_funcToMethod(lerpHpr, NodePath)
-del lerpHpr
-#####################################################################
-def lerpHprHPR(self, h, p, r, time, other=None,
-                   blendType="noBlend", auto=None, task=None, shortest=1):
-        """lerpHprHPR(self, float, float, float, float, string="noBlend",
-        string=none, string=none, NodePath=none)
-        Perform a hpr lerp with three floats as the end point
-        """
-        def functorFunc(self = self, h = h, p = p, r = r,
-                        other = other, shortest=shortest):
-            from pandac.PandaModules import HprLerpFunctor
-            # it's individual hpr components
-            if (other != None):
-                # lerp wrt other
-                startHpr = self.getHpr(other)
-                functor = HprLerpFunctor(
-                    self,
-                    startHpr[0], startHpr[1], startHpr[2],
-                    h, p, r, other)
-                if shortest:
-                    functor.takeShortest()
-            else:
-                startHpr = self.getHpr()
-                functor = HprLerpFunctor(
-                    self,
-                    startHpr[0], startHpr[1], startHpr[2],
-                    h, p, r)
-                if shortest:
-                    functor.takeShortest()
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpHprHPR, NodePath)
-del lerpHprHPR
-#####################################################################
-def lerpHprVBase3(self, hpr, time, other=None,
-                      blendType="noBlend", auto=None, task=None, shortest=1):
-        """lerpHprVBase3(self, VBase3, float, string="noBlend", string=none,
-        string=none, NodePath=None)
-        Perform a hpr lerp with a VBase3 as the end point
-        """
-        def functorFunc(self = self, hpr = hpr,
-                        other = other, shortest=shortest):
-            from pandac.PandaModules import HprLerpFunctor
-            # it's a vbase3 hpr
-            if (other != None):
-                # lerp wrt other
-                functor = HprLerpFunctor(
-                    self, (self.getHpr(other)), hpr, other)
-                if shortest:
-                    functor.takeShortest()
-            else:
-                functor = HprLerpFunctor(
-                    self, (self.getHpr()), hpr)
-                if shortest:
-                    functor.takeShortest()
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-Dtool_funcToMethod(lerpHprVBase3, NodePath)
-del lerpHprVBase3
-#####################################################################
-def lerpPos(self, *posArgs, **keyArgs):
-        """lerpPos(self, *positionArgs, **keywordArgs)
-        Determine whether to call lerpPosXYZ or lerpPosPoint3
-        based on the first argument
-        """
-        # check to see if lerping with three
-        # floats or a Point3
-        if (len(posArgs) == 4):
-            return apply(self.lerpPosXYZ, posArgs, keyArgs)
-        elif(len(posArgs) == 2):
-            return apply(self.lerpPosPoint3, posArgs, keyArgs)
-        else:
-            # bad number off args
-            raise Exception("Error: NodePath.lerpPos: bad number of args")
-
-Dtool_funcToMethod(lerpPos, NodePath)
-del lerpPos
-#####################################################################
-def lerpPosXYZ(self, x, y, z, time, other=None,
-                   blendType="noBlend", auto=None, task=None):
-        """lerpPosXYZ(self, float, float, float, float, string="noBlend",
-        string=None, NodePath=None)
-        Perform a pos lerp with three floats as the end point
-        """
-        def functorFunc(self = self, x = x, y = y, z = z, other = other):
-            from pandac.PandaModules import PosLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                startPos = self.getPos(other)
-                functor = PosLerpFunctor(self,
-                                         startPos[0], startPos[1], startPos[2],
-                                         x, y, z, other)
-            else:
-                startPos = self.getPos()
-                functor = PosLerpFunctor(self, startPos[0],
-                                         startPos[1], startPos[2], x, y, z)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return  self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpPosXYZ, NodePath)
-del lerpPosXYZ
-#####################################################################
-def lerpPosPoint3(self, pos, time, other=None,
-                      blendType="noBlend", auto=None, task=None):
-        """lerpPosPoint3(self, Point3, float, string="noBlend", string=None,
-        string=None, NodePath=None)
-        Perform a pos lerp with a Point3 as the end point
-        """
-        def functorFunc(self = self, pos = pos, other = other):
-            from pandac.PandaModules import PosLerpFunctor
-            if (other != None):
-                #lerp wrt other
-                functor = PosLerpFunctor(
-                    self, (self.getPos(other)), pos, other)
-            else:
-                functor = PosLerpFunctor(
-                    self, (self.getPos()), pos)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-Dtool_funcToMethod(lerpPosPoint3, NodePath)
-del lerpPosPoint3
-#####################################################################
-def lerpPosHpr(self, *posArgs, **keyArgs):
-        """lerpPosHpr(self, *positionArgs, **keywordArgs)
-        Determine whether to call lerpPosHprXYZHPR or lerpHprPoint3VBase3
-        based on first argument
-        """
-        # check to see if lerping with
-        # six floats or a Point3 and a VBase3
-        if (len(posArgs) == 7):
-            return apply(self.lerpPosHprXYZHPR, posArgs, keyArgs)
-        elif(len(posArgs) == 3):
-            return apply(self.lerpPosHprPoint3VBase3, posArgs, keyArgs)
-        else:
-            # bad number off args
-            raise Exception("Error: NodePath.lerpPosHpr: bad number of args")
-
-Dtool_funcToMethod(lerpPosHpr, NodePath)
-del lerpPosHpr
-#####################################################################
-def lerpPosHprPoint3VBase3(self, pos, hpr, time, other=None,
-                               blendType="noBlend", auto=None, task=None, shortest=1):
-        """lerpPosHprPoint3VBase3(self, Point3, VBase3, string="noBlend",
-        string=none, string=none, NodePath=None)
-        """
-        def functorFunc(self = self, pos = pos, hpr = hpr,
-                        other = other, shortest=shortest):
-            from pandac.PandaModules import PosHprLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                startPos = self.getPos(other)
-                startHpr = self.getHpr(other)
-                functor = PosHprLerpFunctor(
-                    self, startPos, pos,
-                    startHpr, hpr, other)
-                if shortest:
-                    functor.takeShortest()
-            else:
-                startPos = self.getPos()
-                startHpr = self.getHpr()
-                functor = PosHprLerpFunctor(
-                    self, startPos, pos,
-                    startHpr, hpr)
-                if shortest:
-                    functor.takeShortest()
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpPosHprPoint3VBase3, NodePath)
-del lerpPosHprPoint3VBase3
-#####################################################################
-def lerpPosHprXYZHPR(self, x, y, z, h, p, r, time, other=None,
-                         blendType="noBlend", auto=None, task=None, shortest=1):
-        """lerpPosHpr(self, float, string="noBlend", string=none,
-        string=none, NodePath=None)
-        """
-        def functorFunc(self = self, x = x, y = y, z = z,
-                        h = h, p = p, r = r, other = other, shortest=shortest):
-            from pandac.PandaModules import PosHprLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                startPos = self.getPos(other)
-                startHpr = self.getHpr(other)
-                functor = PosHprLerpFunctor(self,
-                                            startPos[0], startPos[1],
-                                            startPos[2], x, y, z,
-                                            startHpr[0], startHpr[1],
-                                            startHpr[2], h, p, r,
-                                            other)
-                if shortest:
-                    functor.takeShortest()
-            else:
-                startPos = self.getPos()
-                startHpr = self.getHpr()
-                functor = PosHprLerpFunctor(self,
-                                            startPos[0], startPos[1],
-                                            startPos[2], x, y, z,
-                                            startHpr[0], startHpr[1],
-                                            startHpr[2], h, p, r)
-                if shortest:
-                    functor.takeShortest()
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-Dtool_funcToMethod(lerpPosHprXYZHPR, NodePath)
-del lerpPosHprXYZHPR
-#####################################################################
-def lerpPosHprScale(self, pos, hpr, scale, time, other=None,
-                        blendType="noBlend", auto=None, task=None, shortest=1):
-        """lerpPosHpr(self, Point3, VBase3, float, float, string="noBlend",
-        string=none, string=none, NodePath=None)
-        Only one case, no need for extra args. Call the appropriate lerp
-        (auto, spawned, or blocking) based on how(if) a task name is given
-        """
-        def functorFunc(self = self, pos = pos, hpr = hpr,
-                        scale = scale, other = other, shortest=shortest):
-            from pandac.PandaModules import PosHprScaleLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                startPos = self.getPos(other)
-                startHpr = self.getHpr(other)
-                startScale = self.getScale(other)
-                functor = PosHprScaleLerpFunctor(self,
-                                                 startPos, pos,
-                                                 startHpr, hpr,
-                                                 startScale, scale, other)
-                if shortest:
-                    functor.takeShortest()
-            else:
-                startPos = self.getPos()
-                startHpr = self.getHpr()
-                startScale = self.getScale()
-                functor = PosHprScaleLerpFunctor(self,
-                                                 startPos, pos,
-                                                 startHpr, hpr,
-                                                 startScale, scale)
-                if shortest:
-                    functor.takeShortest()
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-Dtool_funcToMethod(lerpPosHprScale, NodePath)
-del lerpPosHprScale
-#####################################################################
-def lerpScale(self, *posArgs, **keyArgs):
-        """lerpSclae(self, *positionArgs, **keywordArgs)
-        Determine whether to call lerpScaleXYZ or lerpScaleaseV3
-        based on the first argument
-        """
-        # check to see if lerping with three
-        # floats or a Point3
-        if (len(posArgs) == 4):
-            return apply(self.lerpScaleXYZ, posArgs, keyArgs)
-        elif(len(posArgs) == 2):
-            return apply(self.lerpScaleVBase3, posArgs, keyArgs)
-        else:
-            # bad number off args
-            raise Exception("Error: NodePath.lerpScale: bad number of args")
-
-Dtool_funcToMethod(lerpScale, NodePath)
-del lerpScale
-#####################################################################
-def lerpScaleVBase3(self, scale, time, other=None,
-                        blendType="noBlend", auto=None, task=None):
-        """lerpPos(self, VBase3, float, string="noBlend", string=none,
-        string=none, NodePath=None)
-        """
-        def functorFunc(self = self, scale = scale, other = other):
-            from pandac.PandaModules import ScaleLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                functor = ScaleLerpFunctor(self,
-                                           (self.getScale(other)),
-                                           scale, other)
-            else:
-                functor = ScaleLerpFunctor(self,
-                                           (self.getScale()), scale)
-
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-Dtool_funcToMethod(lerpScaleVBase3, NodePath)
-del lerpScaleVBase3
-#####################################################################
-def lerpScaleXYZ(self, sx, sy, sz, time, other=None,
-                     blendType="noBlend", auto=None, task=None):
-        """lerpPos(self, float, float, float, float, string="noBlend",
-        string=none, string=none, NodePath=None)
-        """
-        def functorFunc(self = self, sx = sx, sy = sy, sz = sz, other = other):
-            from pandac.PandaModules import ScaleLerpFunctor
-            if (other != None):
-                # lerp wrt other
-                startScale = self.getScale(other)
-                functor = ScaleLerpFunctor(self,
-                                           startScale[0], startScale[1],
-                                           startScale[2], sx, sy, sz, other)
-            else:
-                startScale = self.getScale()
-                functor = ScaleLerpFunctor(self,
-                                           startScale[0], startScale[1],
-                                           startScale[2], sx, sy, sz)
-            return functor
-        #determine whether to use auto, spawned, or blocking lerp
-        if (auto != None):
-            return self.__autoLerp(functorFunc, time, blendType, auto)
-        elif (task != None):
-            return self.__lerp(functorFunc, time, blendType, task)
-        else:
-            return self.__lerp(functorFunc, time, blendType)
-
-
-
-
-Dtool_funcToMethod(lerpScaleXYZ, NodePath)
-del lerpScaleXYZ
-#####################################################################
 def place(self):
 def place(self):
         base.startDirect(fWantTk = 1)
         base.startDirect(fWantTk = 1)
         from direct.tkpanels import Placer
         from direct.tkpanels import Placer
@@ -1253,8 +553,8 @@ Dtool_funcToMethod(colorScaleInterval, NodePath)
 del colorScaleInterval
 del colorScaleInterval
 #####################################################################
 #####################################################################
 def attachCollisionSphere(self, name, cx, cy, cz, r, fromCollide, intoCollide):
 def attachCollisionSphere(self, name, cx, cy, cz, r, fromCollide, intoCollide):
-        from pandac.PandaModules import CollisionSphere
-        from pandac.PandaModules import CollisionNode
+        from panda3d.core import CollisionSphere
+        from panda3d.core import CollisionNode
         coll = CollisionSphere(cx, cy, cz, r)
         coll = CollisionSphere(cx, cy, cz, r)
         collNode = CollisionNode(name)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
         collNode.addSolid(coll)
@@ -1267,8 +567,8 @@ Dtool_funcToMethod(attachCollisionSphere, NodePath)
 del attachCollisionSphere
 del attachCollisionSphere
 #####################################################################
 #####################################################################
 def attachCollisionSegment(self, name, ax, ay, az, bx, by, bz, fromCollide, intoCollide):
 def attachCollisionSegment(self, name, ax, ay, az, bx, by, bz, fromCollide, intoCollide):
-        from pandac.PandaModules import CollisionSegment
-        from pandac.PandaModules import CollisionNode
+        from panda3d.core import CollisionSegment
+        from panda3d.core import CollisionNode
         coll = CollisionSegment(ax, ay, az, bx, by, bz)
         coll = CollisionSegment(ax, ay, az, bx, by, bz)
         collNode = CollisionNode(name)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
         collNode.addSolid(coll)
@@ -1281,8 +581,8 @@ Dtool_funcToMethod(attachCollisionSegment, NodePath)
 del attachCollisionSegment
 del attachCollisionSegment
 #####################################################################
 #####################################################################
 def attachCollisionRay(self, name, ox, oy, oz, dx, dy, dz, fromCollide, intoCollide):
 def attachCollisionRay(self, name, ox, oy, oz, dx, dy, dz, fromCollide, intoCollide):
-        from pandac.PandaModules import CollisionRay
-        from pandac.PandaModules import CollisionNode
+        from panda3d.core import CollisionRay
+        from panda3d.core import CollisionNode
         coll = CollisionRay(ox, oy, oz, dx, dy, dz)
         coll = CollisionRay(ox, oy, oz, dx, dy, dz)
         collNode = CollisionNode(name)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
         collNode.addSolid(coll)
@@ -1296,7 +596,7 @@ del attachCollisionRay
 #####################################################################
 #####################################################################
 def flattenMultitex(self, stateFrom = None, target = None,
 def flattenMultitex(self, stateFrom = None, target = None,
                         useGeom = 0, allowTexMat = 0, win = None):
                         useGeom = 0, allowTexMat = 0, win = None):
-        from pandac.PandaModules import MultitexReducer
+        from panda3d.core import MultitexReducer
         mr = MultitexReducer()
         mr = MultitexReducer()
         if target != None:
         if target != None:
             mr.setTarget(target)
             mr.setTarget(target)
@@ -1466,26 +766,31 @@ del r_constructCollisionTree
 
 
 #####################################################################
 #####################################################################
 def analyze(self):
 def analyze(self):
-        from pandac.PandaModules import SceneGraphAnalyzer
+        """
+        Analyzes the geometry below this node and reports the
+        number of vertices, triangles, etc.  This is the same
+        information reported by the bam-info program.
+        """
+        from panda3d.core import SceneGraphAnalyzer
         sga = SceneGraphAnalyzer()
         sga = SceneGraphAnalyzer()
         sga.addNode(self.node())
         sga.addNode(self.node())
         if sga.getNumLodNodes() == 0:
         if sga.getNumLodNodes() == 0:
-                print sga
+                print(sga)
         else:
         else:
-                print "At highest LOD:"
+                print("At highest LOD:")
                 sga2 = SceneGraphAnalyzer()
                 sga2 = SceneGraphAnalyzer()
                 sga2.setLodMode(sga2.LMHighest)
                 sga2.setLodMode(sga2.LMHighest)
                 sga2.addNode(self.node())
                 sga2.addNode(self.node())
-                print sga2
+                print(sga2)
 
 
-                print "\nAt lowest LOD:"
+                print("\nAt lowest LOD:")
                 sga2.clear()
                 sga2.clear()
                 sga2.setLodMode(sga2.LMLowest)
                 sga2.setLodMode(sga2.LMLowest)
                 sga2.addNode(self.node())
                 sga2.addNode(self.node())
-                print sga2
+                print(sga2)
 
 
-                print "\nAll nodes:"
-                print sga
+                print("\nAll nodes:")
+                print(sga)
 
 
 Dtool_funcToMethod(analyze, NodePath)
 Dtool_funcToMethod(analyze, NodePath)
 del analyze
 del analyze

+ 1 - 1
direct/src/extensions_native/VBase3_extensions.py

@@ -14,7 +14,7 @@ def asTuple(self):
     """
     """
     Returns the vector as a tuple.
     Returns the vector as a tuple.
     """
     """
-    print "Warning: VBase3.asTuple() is no longer needed and deprecated.  Use the vector directly instead."
+    print("Warning: VBase3.asTuple() is no longer needed and deprecated.  Use the vector directly instead.")
     return tuple(self)
     return tuple(self)
 Dtool_funcToMethod(asTuple, VBase3)
 Dtool_funcToMethod(asTuple, VBase3)
 del asTuple
 del asTuple

+ 1 - 1
direct/src/extensions_native/VBase4_extensions.py

@@ -14,7 +14,7 @@ def asTuple(self):
     """
     """
     Returns the vector as a tuple.
     Returns the vector as a tuple.
     """
     """
-    print "Warning: VBase4.asTuple() is no longer needed and deprecated.  Use the vector directly instead."
+    print("Warning: VBase4.asTuple() is no longer needed and deprecated.  Use the vector directly instead.")
     return tuple(self)
     return tuple(self)
 
 
 Dtool_funcToMethod(asTuple, VBase4)
 Dtool_funcToMethod(asTuple, VBase4)

+ 28 - 0
direct/src/extensions_native/core_extensions.py

@@ -0,0 +1,28 @@
+import sys
+
+main_dir = Filename()
+
+if sys.argv and sys.argv[0]:
+    main_dir = Filename.from_os_specific(sys.argv[0])
+
+if main_dir.empty():
+    # We must be running in the Python interpreter directly, so return the CWD.
+    main_dir = ExecutionEnvironment.get_cwd()
+else:
+    main_dir.make_absolute()
+    main_dir = Filename(main_dir.get_dirname())
+ExecutionEnvironment.shadow_environment_variable('MAIN_DIR', main_dir.to_os_specific())
+del sys, main_dir
+
+
+def Dtool_funcToMethod(func, cls, method_name=None):
+    """Adds func to class so it is an accessible method; use method_name to specify the name to be used for calling the method.
+    The new method is accessible to any instance immediately."""
+    #if sys.version_info < (3, 0):
+    #    func.im_class = cls
+    func.im_func = func
+    func.im_self = None
+    if not method_name:
+        method_name = func.__name__
+    cls.DtoolClassDict[method_name] = func;
+

+ 2 - 4
direct/src/ffi/DoGenPyCode.py

@@ -5,8 +5,6 @@ the user to specify alternate parameters on the command line. """
 import getopt
 import getopt
 import sys
 import sys
 import os
 import os
-import glob
-import types
 import time
 import time
 from direct.ffi import FFIConstants
 from direct.ffi import FFIConstants
 
 
@@ -224,7 +222,7 @@ def doErrorCheck():
         FFIConstants.CodeModuleNameList = codeLibs
         FFIConstants.CodeModuleNameList = codeLibs
 
 
 def generateNativeWrappers():
 def generateNativeWrappers():
-    from direct.extensions_native.extension_native_helpers import Dtool_FindModule, Dtool_PreloadDLL
+    from direct.extensions_native.extension_native_helpers import Dtool_PreloadDLL
 
 
     # Empty out the output directories of unnecessary crud from
     # Empty out the output directories of unnecessary crud from
     # previous runs before we begin.
     # previous runs before we begin.
@@ -337,7 +335,7 @@ def run():
 
 
     if doHTML:
     if doHTML:
         from direct.directscripts import gendocs
         from direct.directscripts import gendocs
-        from pandac.PandaModules import PandaSystem
+        from panda3d.core import PandaSystem
         versionString = '%s %s' % (
         versionString = '%s %s' % (
             PandaSystem.getDistributor(), PandaSystem.getVersionString())
             PandaSystem.getDistributor(), PandaSystem.getVersionString())
 
 

+ 0 - 1
direct/src/ffi/FFITypes.py

@@ -8,7 +8,6 @@ They get constructed by and stored in FFIInterrogateDatabase.
 
 
 """
 """
 
 
-import sys
 import os
 import os
 import string
 import string
 import FFIConstants
 import FFIConstants

+ 0 - 1
direct/src/ffi/jGenPyCode.py

@@ -72,7 +72,6 @@ if (EXTENSIONS is None):
 ##############################################################
 ##############################################################
 
 
 from direct.ffi import DoGenPyCode
 from direct.ffi import DoGenPyCode
-from direct.ffi import FFIConstants
 DoGenPyCode.outputCodeDir = PANDAC
 DoGenPyCode.outputCodeDir = PANDAC
 DoGenPyCode.outputHTMLDir = os.path.join(PANDAC,"..","doc")
 DoGenPyCode.outputHTMLDir = os.path.join(PANDAC,"..","doc")
 DoGenPyCode.directDir = DIRECT
 DoGenPyCode.directDir = DIRECT

+ 2 - 2
direct/src/filter/CommonFilters.py

@@ -19,8 +19,8 @@ from FilterManager import FilterManager
 from panda3d.core import LVecBase4, LPoint2
 from panda3d.core import LVecBase4, LPoint2
 from panda3d.core import Filename
 from panda3d.core import Filename
 from panda3d.core import AuxBitplaneAttrib
 from panda3d.core import AuxBitplaneAttrib
-from panda3d.core import RenderState, Texture, Shader, ATSNone
-import sys,os
+from panda3d.core import Texture, Shader, ATSNone
+import os
 
 
 CARTOON_BODY="""
 CARTOON_BODY="""
 float4 cartoondelta = k_cartoonseparation * texpix_txaux.xwyw;
 float4 cartoondelta = k_cartoonseparation * texpix_txaux.xwyw;

+ 3 - 4
direct/src/filter/FilterManager.py

@@ -14,13 +14,12 @@ Still need to implement:
 
 
 """
 """
 
 
-from panda3d.core import NodePath, PandaNode
-from panda3d.core import RenderState, Texture, Shader
+from panda3d.core import NodePath
+from panda3d.core import Texture
 from panda3d.core import CardMaker
 from panda3d.core import CardMaker
-from panda3d.core import TextureStage
 from panda3d.core import GraphicsPipe, GraphicsOutput
 from panda3d.core import GraphicsPipe, GraphicsOutput
 from panda3d.core import WindowProperties, FrameBufferProperties
 from panda3d.core import WindowProperties, FrameBufferProperties
-from panda3d.core import Camera, DisplayRegion
+from panda3d.core import Camera
 from panda3d.core import OrthographicLens
 from panda3d.core import OrthographicLens
 from panda3d.core import AuxBitplaneAttrib
 from panda3d.core import AuxBitplaneAttrib
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *

+ 0 - 1
direct/src/fsm/FourState.py

@@ -8,7 +8,6 @@ from direct.directnotify import DirectNotifyGlobal
 #import DistributedObject
 #import DistributedObject
 import ClassicFSM
 import ClassicFSM
 import State
 import State
-from direct.task import Task
 
 
 
 
 class FourState:
 class FourState:

+ 0 - 1
direct/src/fsm/SampleFSM.py

@@ -3,7 +3,6 @@
 __all__ = ['ClassicStyle', 'NewStyle', 'ToonEyes']
 __all__ = ['ClassicStyle', 'NewStyle', 'ToonEyes']
 
 
 import FSM
 import FSM
-from pandac.PandaModules import *
 from direct.task import Task
 from direct.task import Task
 import string
 import string
 
 

+ 0 - 1
direct/src/fsm/State.py

@@ -4,7 +4,6 @@ __all__ = ['State']
 
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import types
 
 
 
 
 class State(DirectObject):
 class State(DirectObject):

+ 1 - 1
direct/src/fsm/StatePush.py

@@ -5,7 +5,7 @@ __all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse',
            'EventArgument', ]
            'EventArgument', ]
 
 
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import types
+
 
 
 class PushesStateChanges:
 class PushesStateChanges:
     # base class for objects that broadcast state changes to a set of subscriber objects
     # base class for objects that broadcast state changes to a set of subscriber objects

+ 1 - 1
direct/src/gui/DirectButton.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectButton']
 __all__ = ['DirectButton']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 
 

+ 1 - 1
direct/src/gui/DirectCheckBox.py

@@ -1,5 +1,5 @@
 from direct.gui.DirectGui import *
 from direct.gui.DirectGui import *
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 
 
 class DirectCheckBox(DirectButton):
 class DirectCheckBox(DirectButton):

+ 1 - 2
direct/src/gui/DirectCheckButton.py

@@ -2,8 +2,7 @@
 
 
 __all__ = ['DirectCheckButton']
 __all__ = ['DirectCheckButton']
 
 
-from pandac.PandaModules import *
-import DirectGuiGlobals as DGG
+from panda3d.core import *
 from DirectButton import *
 from DirectButton import *
 from DirectLabel import *
 from DirectLabel import *
 
 

+ 1 - 1
direct/src/gui/DirectDialog.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 from DirectButton import *
 from DirectButton import *

+ 1 - 1
direct/src/gui/DirectEntry.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectEntry']
 __all__ = ['DirectEntry']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 from OnscreenText import OnscreenText
 from OnscreenText import OnscreenText

+ 2 - 4
direct/src/gui/DirectEntryScroll.py

@@ -1,6 +1,6 @@
 __all__ = ['DirectEntryScroll']
 __all__ = ['DirectEntryScroll']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectScrolledFrame import *
 from DirectScrolledFrame import *
 from DirectFrame import *
 from DirectFrame import *
@@ -114,6 +114,4 @@ class DirectEntryScroll(DirectFrame):
         
         
     def resetCanvas(self):
     def resetCanvas(self):
         self.canvas.setPos(0,0,0)
         self.canvas.setPos(0,0,0)
-        
-        
-        
+

+ 2 - 2
direct/src/gui/DirectFrame.py

@@ -2,12 +2,12 @@
 
 
 __all__ = ['DirectFrame']
 __all__ = ['DirectFrame']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectGuiBase import *
 from DirectGuiBase import *
 from OnscreenImage import OnscreenImage
 from OnscreenImage import OnscreenImage
 from OnscreenGeom import OnscreenGeom
 from OnscreenGeom import OnscreenGeom
-import string, types
+import types
 
 
 class DirectFrame(DirectGuiWidget):
 class DirectFrame(DirectGuiWidget):
     DefDynGroups = ('text', 'geom', 'image')
     DefDynGroups = ('text', 'geom', 'image')

+ 7 - 9
direct/src/gui/DirectGuiBase.py

@@ -3,7 +3,8 @@
 __all__ = ['DirectGuiBase', 'DirectGuiWidget']
 __all__ = ['DirectGuiBase', 'DirectGuiWidget']
 
 
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import get_config_showbase
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from OnscreenText import *
 from OnscreenText import *
 from OnscreenGeom import *
 from OnscreenGeom import *
@@ -11,9 +12,7 @@ from OnscreenImage import *
 from direct.directtools.DirectUtil import ROUND_TO
 from direct.directtools.DirectUtil import ROUND_TO
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject
 from direct.task import Task
 from direct.task import Task
-from direct.showbase import ShowBase
 from direct.showbase.PythonUtil import recordCreationStackStr
 from direct.showbase.PythonUtil import recordCreationStackStr
-from pandac.PandaModules import PStatCollector
 import types
 import types
 
 
 guiObjectCollector = PStatCollector("Client::GuiObjects")
 guiObjectCollector = PStatCollector("Client::GuiObjects")
@@ -632,7 +631,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         """
         """
         # Need to tack on gui item specific id
         # Need to tack on gui item specific id
         gEvent = event + self.guiId
         gEvent = event + self.guiId
-        if base.config.GetBool('debug-directgui-msgs', False):
+        if get_config_showbase().GetBool('debug-directgui-msgs', False):
             from direct.showbase.PythonUtil import StackTrace
             from direct.showbase.PythonUtil import StackTrace
             print gEvent
             print gEvent
             print StackTrace()
             print StackTrace()
@@ -655,7 +654,7 @@ def setGuiGridSpacing(spacing):
 # this should trigger off of __dev__, but it's not available at this point.
 # this should trigger off of __dev__, but it's not available at this point.
 # __debug__ works because the production client is not __debug__ and the
 # __debug__ works because the production client is not __debug__ and the
 # production AI doesn't create any GUI.
 # production AI doesn't create any GUI.
-if config.GetBool('record-gui-creation-stack', __debug__):
+if get_config_showbase().GetBool('record-gui-creation-stack', __debug__):
     # this will help track down the code that created DirectGui objects
     # this will help track down the code that created DirectGui objects
     # call obj.printCreationStackTrace() to figure out what code created it
     # call obj.printCreationStackTrace() to figure out what code created it
     DirectGuiBase = recordCreationStackStr(DirectGuiBase)
     DirectGuiBase = recordCreationStackStr(DirectGuiBase)
@@ -668,8 +667,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     # Determine the default initial state for inactive (or
     # Determine the default initial state for inactive (or
     # unclickable) components.  If we are in edit mode, these are
     # unclickable) components.  If we are in edit mode, these are
     # actually clickable by default.
     # actually clickable by default.
-    #guiEdit = base.config.GetBool('direct-gui-edit', 0)
-    guiEdit = config.GetBool('direct-gui-edit', 0)
+    guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0)
     if guiEdit:
     if guiEdit:
         inactiveInitState = DGG.NORMAL
         inactiveInitState = DGG.NORMAL
     else:
     else:
@@ -1069,8 +1067,8 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     def printConfig(self, indent = 0):
     def printConfig(self, indent = 0):
         space = ' ' * indent
         space = ' ' * indent
         print space + self.guiId, '-', self.__class__.__name__
         print space + self.guiId, '-', self.__class__.__name__
-        print space + 'Pos:   ' + self.getPos().pPrintValues()
-        print space + 'Scale: ' + self.getScale().pPrintValues()
+        print space + 'Pos:   %s' % tuple(self.getPos())
+        print space + 'Scale: %s' % tuple(self.getScale())
         # Print out children info
         # Print out children info
         for child in self.getChildren():
         for child in self.getChildren():
             messenger.send(DGG.PRINT + child.getName(), [indent + 2])
             messenger.send(DGG.PRINT + child.getName(), [indent + 2])

+ 1 - 1
direct/src/gui/DirectGuiGlobals.py

@@ -7,7 +7,7 @@ __all__ = []
 Global definitions used by Direct Gui Classes and handy constants
 Global definitions used by Direct Gui Classes and handy constants
 that can be used during widget construction
 that can be used during widget construction
 """
 """
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 defaultFont = None
 defaultFont = None
 defaultFontFunc = TextNode.getDefaultFont
 defaultFontFunc = TextNode.getDefaultFont

+ 3 - 1
direct/src/gui/DirectGuiTest.py

@@ -4,11 +4,13 @@ __all__ = []
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
-    from direct.directbase import DirectStart
+    from direct.showbase.ShowBase import ShowBase
     from DirectGui import *
     from DirectGui import *
     #from whrandom import *
     #from whrandom import *
     from random import *
     from random import *
 
 
+    base = ShowBase()
+
     # EXAMPLE CODE
     # EXAMPLE CODE
     # Load a model
     # Load a model
     smiley = loader.loadModel('models/misc/smiley')
     smiley = loader.loadModel('models/misc/smiley')

+ 1 - 2
direct/src/gui/DirectLabel.py

@@ -2,8 +2,7 @@
 
 
 __all__ = ['DirectLabel']
 __all__ = ['DirectLabel']
 
 
-from pandac.PandaModules import *
-import DirectGuiGlobals as DGG
+from panda3d.core import *
 from DirectFrame import *
 from DirectFrame import *
 
 
 class DirectLabel(DirectFrame):
 class DirectLabel(DirectFrame):

+ 1 - 1
direct/src/gui/DirectOptionMenu.py

@@ -4,7 +4,7 @@ __all__ = ['DirectOptionMenu']
 
 
 import types
 import types
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectButton import *
 from DirectButton import *
 from DirectLabel import *
 from DirectLabel import *

+ 1 - 1
direct/src/gui/DirectRadioButton.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectRadioButton']
 __all__ = ['DirectRadioButton']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectButton import *
 from DirectButton import *
 from DirectLabel import *
 from DirectLabel import *

+ 1 - 1
direct/src/gui/DirectScrollBar.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectScrollBar']
 __all__ = ['DirectScrollBar']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 from DirectButton import *
 from DirectButton import *

+ 1 - 1
direct/src/gui/DirectScrolledFrame.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectScrolledFrame']
 __all__ = ['DirectScrolledFrame']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 from DirectScrollBar import *
 from DirectScrollBar import *

+ 2 - 2
direct/src/gui/DirectScrolledList.py

@@ -2,13 +2,13 @@
 
 
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.task.Task import Task
 from direct.task.Task import Task
 from DirectFrame import *
 from DirectFrame import *
 from DirectButton import *
 from DirectButton import *
-import string, types
+import types
 
 
 
 
 class DirectScrolledListItem(DirectButton):
 class DirectScrolledListItem(DirectButton):

+ 1 - 1
direct/src/gui/DirectSlider.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectSlider']
 __all__ = ['DirectSlider']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 from DirectButton import *
 from DirectButton import *

+ 1 - 1
direct/src/gui/DirectWaitBar.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['DirectWaitBar']
 __all__ = ['DirectWaitBar']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 from DirectFrame import *
 import types
 import types

+ 2 - 3
direct/src/gui/OnscreenGeom.py

@@ -2,10 +2,9 @@
 
 
 __all__ = ['OnscreenGeom']
 __all__ = ['OnscreenGeom']
 
 
-from pandac.PandaModules import *
-import DirectGuiGlobals as DGG
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import string,types
+import types
 
 
 class OnscreenGeom(DirectObject, NodePath):
 class OnscreenGeom(DirectObject, NodePath):
     def __init__(self, geom = None,
     def __init__(self, geom = None,

+ 2 - 3
direct/src/gui/OnscreenImage.py

@@ -2,10 +2,9 @@
 
 
 __all__ = ['OnscreenImage']
 __all__ = ['OnscreenImage']
 
 
-from pandac.PandaModules import *
-import DirectGuiGlobals as DGG
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import string,types
+import types
 
 
 class OnscreenImage(DirectObject, NodePath):
 class OnscreenImage(DirectObject, NodePath):
     def __init__(self, image = None,
     def __init__(self, image = None,

+ 2 - 2
direct/src/gui/OnscreenText.py

@@ -2,10 +2,10 @@
 
 
 __all__ = ['OnscreenText', 'Plain', 'ScreenTitle', 'ScreenPrompt', 'NameConfirm', 'BlackOnWhite']
 __all__ = ['OnscreenText', 'Plain', 'ScreenTitle', 'ScreenPrompt', 'NameConfirm', 'BlackOnWhite']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 import DirectGuiGlobals as DGG
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import string,types
+import types
 
 
 ## These are the styles of text we might commonly see.  They set the
 ## These are the styles of text we might commonly see.  They set the
 ## overall appearance of the text according to one of a number of
 ## overall appearance of the text according to one of a number of

+ 2 - 1
direct/src/interval/ActorInterval.py

@@ -2,7 +2,8 @@
 
 
 __all__ = ['ActorInterval', 'LerpAnimInterval']
 __all__ = ['ActorInterval', 'LerpAnimInterval']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 import Interval
 import math
 import math

+ 2 - 1
direct/src/interval/AnimControlInterval.py

@@ -2,7 +2,8 @@
 
 
 __all__ = ['AnimControlInterval']
 __all__ = ['AnimControlInterval']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 import Interval
 import math
 import math

+ 2 - 2
direct/src/interval/FunctionInterval.py

@@ -2,11 +2,11 @@
 
 
 __all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait']
 __all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.showbase.MessengerGlobal import *
 from direct.showbase.MessengerGlobal import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 import Interval
 import Interval
-import types
 
 
 
 
 #############################################################
 #############################################################

+ 2 - 1
direct/src/interval/IndirectInterval.py

@@ -2,7 +2,8 @@
 
 
 __all__ = ['IndirectInterval']
 __all__ = ['IndirectInterval']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 import Interval
 import LerpBlendHelpers
 import LerpBlendHelpers

+ 2 - 3
direct/src/interval/Interval.py

@@ -4,10 +4,9 @@ __all__ = ['Interval']
 
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from pandac.PandaModules import *
 from direct.task.Task import Task, TaskManager
 from direct.task.Task import Task, TaskManager
-from direct.showbase import PythonUtil
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 import math
 import math
 
 
 class Interval(DirectObject):
 class Interval(DirectObject):

+ 10 - 8
direct/src/interval/IntervalGlobal.py

@@ -10,15 +10,17 @@ from FunctionInterval import *
 from LerpInterval import *
 from LerpInterval import *
 from IndirectInterval import *
 from IndirectInterval import *
 from MopathInterval import *
 from MopathInterval import *
-import pandac.PandaModules
-##Some people may have the particle system compiled out
-if hasattr( pandac.PandaModules, 'ParticleSystem' ):
-    from ParticleInterval import *
+try:
+    import panda3d.physics
+    ##Some people may have the particle system compiled out
+    if hasattr( panda3d.physics, 'ParticleSystem' ):
+        from ParticleInterval import *
+        if __debug__:
+            from TestInterval import *
+except ImportError:
+    pass
 from SoundInterval import *
 from SoundInterval import *
 from ProjectileInterval import *
 from ProjectileInterval import *
 from MetaInterval import *
 from MetaInterval import *
 from IntervalManager import *
 from IntervalManager import *
-if __debug__:
-    if hasattr( pandac.PandaModules, 'ParticleSystem' ):
-        from TestInterval import *
-from pandac.PandaModules import WaitInterval
+from panda3d.direct import WaitInterval

+ 2 - 4
direct/src/interval/IntervalManager.py

@@ -2,12 +2,10 @@
 
 
 __all__ = ['IntervalManager', 'ivalMgr']
 __all__ = ['IntervalManager', 'ivalMgr']
 
 
-from pandac.PandaModules import *
-from pandac import PandaModules
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.showbase import EventManager
 from direct.showbase import EventManager
-import Interval
-import types
 import fnmatch
 import fnmatch
 
 
 class IntervalManager(CIntervalManager):
 class IntervalManager(CIntervalManager):

+ 5 - 3
direct/src/interval/IntervalTest.py

@@ -4,13 +4,15 @@ __all__ = []
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
-    from direct.directbase import DirectStart
-    from pandac.PandaModules import *
+    from direct.showbase.ShowBase import ShowBase
+    from panda3d.core import *
     from IntervalGlobal import *
     from IntervalGlobal import *
     from direct.actor.Actor import *
     from direct.actor.Actor import *
 
 
     from direct.directutil import Mopath
     from direct.directutil import Mopath
 
 
+    base = ShowBase()
+
     boat = loader.loadModel('models/misc/smiley')
     boat = loader.loadModel('models/misc/smiley')
     boat.reparentTo(render)
     boat.reparentTo(render)
 
 
@@ -205,4 +207,4 @@ if __name__ == "__main__":
         # return mt
         # return mt
 
 
     test(5)
     test(5)
-    run()
+    base.run()

+ 2 - 1
direct/src/interval/LerpInterval.py

@@ -12,7 +12,8 @@ __all__ = [
     'LerpFunctionInterval', 'LerpFunc','LerpFunctionNoStateInterval','LerpFuncNS'
     'LerpFunctionInterval', 'LerpFunc','LerpFunctionNoStateInterval','LerpFuncNS'
     ]
     ]
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 import Interval
 import LerpBlendHelpers
 import LerpBlendHelpers

+ 5 - 4
direct/src/interval/MetaInterval.py

@@ -2,14 +2,15 @@
 
 
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 from IntervalManager import ivalMgr
 from IntervalManager import ivalMgr
 import Interval
 import Interval
-from direct.task.Task import Task, TaskManager
+from direct.task.Task import TaskManager
 import types
 import types
-if __debug__:
-    import direct.showbase.PythonUtil as PythonUtil
+#if __debug__:
+#    import direct.showbase.PythonUtil as PythonUtil
 
 
 PREVIOUS_END = CMetaInterval.RSPreviousEnd
 PREVIOUS_END = CMetaInterval.RSPreviousEnd
 PREVIOUS_START = CMetaInterval.RSPreviousBegin
 PREVIOUS_START = CMetaInterval.RSPreviousBegin

+ 2 - 1
direct/src/interval/MopathInterval.py

@@ -3,7 +3,8 @@
 __all__ = ['MopathInterval']
 __all__ = ['MopathInterval']
 
 
 import LerpInterval
 import LerpInterval
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 
 
 # import Mopath
 # import Mopath

+ 2 - 2
direct/src/interval/ParticleInterval.py

@@ -6,11 +6,11 @@ __all__ = ['ParticleInterval']
 Contains the ParticleInterval class
 Contains the ParticleInterval class
 """
 """
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from Interval import Interval
 from Interval import Interval
 
 
-from direct.particles import ParticleEffect
 
 
 class ParticleInterval(Interval):
 class ParticleInterval(Interval):
     """
     """

+ 2 - 2
direct/src/interval/ProjectileInterval.py

@@ -2,10 +2,10 @@
 
 
 __all__ = ['ProjectileInterval']
 __all__ = ['ProjectileInterval']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 from Interval import Interval
 from Interval import Interval
-from direct.showbase.PythonUtil import lerp
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
 
 
 class ProjectileInterval(Interval):
 class ProjectileInterval(Interval):

+ 2 - 2
direct/src/interval/ProjectileIntervalTest.py

@@ -2,8 +2,8 @@
 
 
 __all__ = ['doTest']
 __all__ = ['doTest']
 
 
-from pandac.PandaModules import *
-from direct.directbase.DirectStart import *
+from panda3d.core import *
+from panda3d.direct import *
 from IntervalGlobal import *
 from IntervalGlobal import *
 
 
 def doTest():
 def doTest():

+ 2 - 1
direct/src/interval/SoundInterval.py

@@ -2,7 +2,8 @@
 
 
 __all__ = ['SoundInterval']
 __all__ = ['SoundInterval']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 import Interval
 import random
 import random

+ 2 - 2
direct/src/interval/TestInterval.py

@@ -6,11 +6,11 @@ __all__ = ['TestInterval']
 Contains the ParticleInterval class
 Contains the ParticleInterval class
 """
 """
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from Interval import Interval
 from Interval import Interval
 
 
-from direct.particles import ParticleEffect
 
 
 class TestInterval(Interval):
 class TestInterval(Interval):
     # Name counter
     # Name counter

+ 2 - 1
direct/src/motiontrail/MotionTrail.py

@@ -1,6 +1,7 @@
 
 
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.task import Task
 from direct.task import Task
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 
 

+ 16 - 27
direct/src/p3d/AppRunner.py

@@ -9,27 +9,15 @@ runp3d.py for a command-line tool to invoke this module.
 
 
 """
 """
 
 
+__all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]
+
 import sys
 import sys
 import os
 import os
-import types
-import __builtin__
-
-if 'VFSImporter' in sys.modules:
-    # If we've already got a VFSImporter module defined at the
-    # toplevel, we must have come in here by way of the
-    # p3dPythonRun.cxx program, which starts out by importing a frozen
-    # VFSImporter.  Let's make sure we don't have two VFSImporter
-    # modules.
-    import VFSImporter
-    import direct.showbase
-    direct.showbase.VFSImporter = VFSImporter
-    sys.modules['direct.showbase.VFSImporter'] = VFSImporter
-else:
-    # Otherwise, we can import the VFSImporter normally.
-    from direct.showbase import VFSImporter
+import __builtin__ as builtins
 
 
+from direct.showbase import VFSImporter
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from panda3d.core import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, Thread, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString, ConfigPageManager
+from panda3d.core import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString, ConfigPageManager
 from panda3d.direct import init_app_for_gui
 from panda3d.direct import init_app_for_gui
 from panda3d import core
 from panda3d import core
 from direct.stdpy import file, glob
 from direct.stdpy import file, glob
@@ -43,7 +31,7 @@ from direct.p3d.InstalledHostData import InstalledHostData
 from direct.p3d.InstalledPackageData import InstalledPackageData
 from direct.p3d.InstalledPackageData import InstalledPackageData
 
 
 # These imports are read by the C++ wrapper in p3dPythonRun.cxx.
 # These imports are read by the C++ wrapper in p3dPythonRun.cxx.
-from direct.p3d.JavaScript import UndefinedObject, Undefined, ConcreteStruct, BrowserObject
+from direct.p3d.JavaScript import Undefined, ConcreteStruct
 
 
 class ArgumentError(AttributeError):
 class ArgumentError(AttributeError):
     pass
     pass
@@ -471,7 +459,7 @@ class AppRunner(DirectObject):
             file.unlink()
             file.unlink()
             return False
             return False
 
 
-        if not fileSpec.fullVerify(pathname = localPathname):
+        if not fileSpec.fullVerify(pathname = localPathname, notify = self.notify):
             # No good after download.
             # No good after download.
             self.notify.info("%s is still no good after downloading." % (url))
             self.notify.info("%s is still no good after downloading." % (url))
             return False
             return False
@@ -569,14 +557,14 @@ class AppRunner(DirectObject):
             for packageData in hostData.packages:
             for packageData in hostData.packages:
                 totalSize += packageData.totalSize
                 totalSize += packageData.totalSize
         self.notify.info("Total Panda3D disk space used: %s MB" % (
         self.notify.info("Total Panda3D disk space used: %s MB" % (
-            (totalSize + 524288) / 1048576))
+            (totalSize + 524288) // 1048576))
 
 
         if self.verifyContents == self.P3DVCNever:
         if self.verifyContents == self.P3DVCNever:
             # We're not allowed to delete anything anyway.
             # We're not allowed to delete anything anyway.
             return
             return
 
 
         self.notify.info("Configured max usage is: %s MB" % (
         self.notify.info("Configured max usage is: %s MB" % (
-            (self.maxDiskUsage + 524288) / 1048576))
+            (self.maxDiskUsage + 524288) // 1048576))
         if totalSize <= self.maxDiskUsage:
         if totalSize <= self.maxDiskUsage:
             # Still within budget; no need to clean up anything.
             # Still within budget; no need to clean up anything.
             return
             return
@@ -634,13 +622,13 @@ class AppRunner(DirectObject):
         try:
         try:
             taskMgr.run()
             taskMgr.run()
 
 
-        except SystemExit:
+        except SystemExit as err:
             # Presumably the window has already been shut down here, but shut
             # Presumably the window has already been shut down here, but shut
             # it down again for good measure.
             # it down again for good measure.
-            if hasattr(__builtin__, "base"):
+            if hasattr(builtins, "base"):
                 base.destroy()
                 base.destroy()
 
 
-            self.notify.info("Normal exit.")
+            self.notify.info("Normal exit with status %s." % repr(err.code))
             raise
             raise
 
 
         except:
         except:
@@ -696,9 +684,10 @@ class AppRunner(DirectObject):
             # Replace the builtin open and file symbols so user code will get
             # Replace the builtin open and file symbols so user code will get
             # our versions by default, which can open and read files out of
             # our versions by default, which can open and read files out of
             # the multifile.
             # the multifile.
-            __builtin__.file = file.file
-            __builtin__.open = file.open
-            __builtin__.execfile = file.execfile
+            builtins.open = file.open
+            if sys.version_info < (3, 0):
+                builtins.file = file.open
+                builtins.execfile = file.execfile
             os.listdir = file.listdir
             os.listdir = file.listdir
             os.walk = file.walk
             os.walk = file.walk
             os.path.join = file.join
             os.path.join = file.join

+ 2 - 0
direct/src/p3d/DWBPackageInstaller.py

@@ -1,3 +1,5 @@
+__all__ = ["DWBPackageInstaller"]
+
 from direct.p3d.PackageInstaller import PackageInstaller
 from direct.p3d.PackageInstaller import PackageInstaller
 from direct.gui.DirectWaitBar import DirectWaitBar
 from direct.gui.DirectWaitBar import DirectWaitBar
 from direct.gui import DirectGuiGlobals as DGG
 from direct.gui import DirectGuiGlobals as DGG

+ 137 - 62
direct/src/p3d/DeploymentTools.py

@@ -4,8 +4,8 @@ to build for as many platforms as possible. """
 
 
 __all__ = ["Standalone", "Installer"]
 __all__ = ["Standalone", "Installer"]
 
 
-import os, sys, subprocess, tarfile, shutil, time, zipfile, glob, socket, getpass, struct
-from cStringIO import StringIO
+import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct
+from io import BytesIO, TextIOWrapper
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.showbase.AppRunnerGlobal import appRunner
 from direct.showbase.AppRunnerGlobal import appRunner
 from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
 from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
@@ -21,8 +21,8 @@ try:
 except ImportError:
 except ImportError:
     pwd = None
     pwd = None
 
 
-# Make sure this matches with the magic in p3dEmbed.cxx.
-P3DEMBED_MAGIC = "\xFF\x3D\x3D\x00"
+# Make sure this matches with the magic in p3dEmbedMain.cxx.
+P3DEMBED_MAGIC = 0xFF3D3D00
 
 
 # This filter function is used when creating
 # This filter function is used when creating
 # an archive that should be owned by root.
 # an archive that should be owned by root.
@@ -73,7 +73,7 @@ class Standalone:
 
 
         self.tempDir = Filename.temporary("", self.basename, "") + "/"
         self.tempDir = Filename.temporary("", self.basename, "") + "/"
         self.tempDir.makeDir()
         self.tempDir.makeDir()
-        self.host = HostInfo(PandaSystem.getPackageHostUrl(), appRunner = appRunner, hostDir = self.tempDir, asMirror = False)
+        self.host = HostInfo(PandaSystem.getPackageHostUrl(), appRunner = appRunner, hostDir = self.tempDir, asMirror = False, perPlatform = True)
 
 
         self.http = HTTPClient.getGlobalPtr()
         self.http = HTTPClient.getGlobalPtr()
         if not self.host.hasContentsFile:
         if not self.host.hasContentsFile:
@@ -99,6 +99,9 @@ class Standalone:
         if len(platforms) == 0:
         if len(platforms) == 0:
             Standalone.notify.warning("No platforms found to build for!")
             Standalone.notify.warning("No platforms found to build for!")
 
 
+        if 'win32' in platforms and 'win_i386' in platforms:
+            platforms.remove('win32')
+
         outputDir = Filename(outputDir + "/")
         outputDir = Filename(outputDir + "/")
         outputDir.makeDir()
         outputDir.makeDir()
         for platform in platforms:
         for platform in platforms:
@@ -158,10 +161,10 @@ class Standalone:
 
 
         # Find the magic size string and replace it with the real size,
         # Find the magic size string and replace it with the real size,
         # regardless of the endianness of the p3dembed executable.
         # regardless of the endianness of the p3dembed executable.
-        hex_size = hex(size)[2:].rjust(8, "0")
-        enc_size = "".join([chr(int(hex_size[i] + hex_size[i + 1], 16)) for i in range(0, len(hex_size), 2)])
-        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC, enc_size)
-        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC[::-1], enc_size[::-1])
+        p3dembed_data = p3dembed_data.replace(struct.pack('>I', P3DEMBED_MAGIC),
+                                              struct.pack('>I', size))
+        p3dembed_data = p3dembed_data.replace(struct.pack('<I', P3DEMBED_MAGIC),
+                                              struct.pack('<I', size))
 
 
         # Write the output file
         # Write the output file
         Standalone.notify.info("Creating %s..." % output)
         Standalone.notify.info("Creating %s..." % output)
@@ -170,12 +173,15 @@ class Standalone:
         ohandle.write(p3dembed_data)
         ohandle.write(p3dembed_data)
 
 
         # Write out the tokens. Set log_basename to the basename by default
         # Write out the tokens. Set log_basename to the basename by default
-        tokens = {"log_basename" : self.basename}
+        tokens = {"log_basename": self.basename}
         tokens.update(self.tokens)
         tokens.update(self.tokens)
         tokens.update(extraTokens)
         tokens.update(extraTokens)
-        for token in tokens.items():
-            ohandle.write("\0%s=%s" % token)
-        ohandle.write("\0\0")
+        for key, value in tokens.items():
+            ohandle.write(b"\0")
+            ohandle.write(key.encode('ascii'))
+            ohandle.write(b"=")
+            ohandle.write(value.encode())
+        ohandle.write(b"\0\0")
 
 
         # Buffer the p3d file to the output file. 1 MB buffer size.
         # Buffer the p3d file to the output file. 1 MB buffer size.
         phandle = open(self.p3dfile.toOsSpecific(), "rb")
         phandle = open(self.p3dfile.toOsSpecific(), "rb")
@@ -233,7 +239,7 @@ class PackageTree:
         if hostUrl in self.hosts:
         if hostUrl in self.hosts:
             return self.hosts[hostUrl]
             return self.hosts[hostUrl]
 
 
-        host = HostInfo(hostUrl, appRunner = appRunner, hostDir = self.hostDir, asMirror = False)
+        host = HostInfo(hostUrl, appRunner = appRunner, hostDir = self.hostDir, asMirror = False, perPlatform = True)
         if not host.hasContentsFile:
         if not host.hasContentsFile:
             if not host.readContentsFile():
             if not host.readContentsFile():
                 if not host.downloadContentsFile(self.http):
                 if not host.downloadContentsFile(self.http):
@@ -391,7 +397,7 @@ class Icon:
         vfs = VirtualFileSystem.getGlobalPtr()
         vfs = VirtualFileSystem.getGlobalPtr()
         stream = vfs.openWriteFile(fn, False, True)
         stream = vfs.openWriteFile(fn, False, True)
         icns = open(stream, 'wb')
         icns = open(stream, 'wb')
-        icns.write('icns\0\0\0\0')
+        icns.write(b'icns\0\0\0\0')
 
 
         icon_types = {16: 'is32', 32: 'il32', 48: 'ih32', 128: 'it32'}
         icon_types = {16: 'is32', 32: 'il32', 48: 'ih32', 128: 'it32'}
         mask_types = {16: 's8mk', 32: 'l8mk', 48: 'h8mk', 128: 't8mk'}
         mask_types = {16: 's8mk', 32: 'l8mk', 48: 'h8mk', 128: 't8mk'}
@@ -404,7 +410,7 @@ class Icon:
                 if pngtype is None:
                 if pngtype is None:
                     continue
                     continue
                 icns.write(png_types[size])
                 icns.write(png_types[size])
-                icns.write('\0\0\0\0')
+                icns.write(b'\0\0\0\0')
                 start = icns.tell()
                 start = icns.tell()
 
 
                 image.write(stream, "", pngtype)
                 image.write(stream, "", pngtype)
@@ -444,6 +450,7 @@ class Installer:
     notify = directNotify.newCategory("Installer")
     notify = directNotify.newCategory("Installer")
 
 
     def __init__(self, p3dfile, shortname, fullname, version, tokens = {}):
     def __init__(self, p3dfile, shortname, fullname, version, tokens = {}):
+        self.p3dFilename = p3dfile
         if not shortname:
         if not shortname:
             shortname = p3dfile.getBasenameWoExtension()
             shortname = p3dfile.getBasenameWoExtension()
         self.shortname = shortname
         self.shortname = shortname
@@ -477,22 +484,16 @@ class Installer:
         if not self.authoremail and ' ' not in uname:
         if not self.authoremail and ' ' not in uname:
             self.authoremail = "%s@%s" % (uname, socket.gethostname())
             self.authoremail = "%s@%s" % (uname, socket.gethostname())
 
 
-        self.standalone = Standalone(p3dfile, tokens)
-        self.tempDir = Filename.temporary("", self.shortname, "") + "/"
-        self.tempDir.makeDir()
-        self.__tempRoots = {}
-
         # Load the p3d file to read out the required packages
         # Load the p3d file to read out the required packages
         mf = Multifile()
         mf = Multifile()
-        if not mf.openRead(p3dfile):
+        if not mf.openRead(self.p3dFilename):
             Installer.notify.error("Not a Panda3D application: %s" % (p3dfile))
             Installer.notify.error("Not a Panda3D application: %s" % (p3dfile))
             return
             return
 
 
         # Now load the p3dInfo file.
         # Now load the p3dInfo file.
-        self.hostUrl = PandaSystem.getPackageHostUrl()
-        if not self.hostUrl:
-            self.hostUrl = self.standalone.host.hostUrl
+        self.hostUrl = None
         self.requires = []
         self.requires = []
+        self.extracts = []
         i = mf.findSubfile('p3d_info.xml')
         i = mf.findSubfile('p3d_info.xml')
         if i >= 0:
         if i >= 0:
             stream = mf.openReadSubfile(i)
             stream = mf.openReadSubfile(i)
@@ -511,14 +512,54 @@ class Installer:
                         p3dRequires.Attribute('host')))
                         p3dRequires.Attribute('host')))
                     p3dRequires = p3dRequires.NextSiblingElement('requires')
                     p3dRequires = p3dRequires.NextSiblingElement('requires')
 
 
+                p3dExtract = p3dPackage.FirstChildElement('extract')
+                while p3dExtract:
+                    filename = p3dExtract.Attribute('filename')
+                    self.extracts.append(filename)
+                    p3dExtract = p3dExtract.NextSiblingElement('extract')
+
                 if not self.fullname:
                 if not self.fullname:
                     p3dConfig = p3dPackage.FirstChildElement('config')
                     p3dConfig = p3dPackage.FirstChildElement('config')
                     if p3dConfig:
                     if p3dConfig:
                         self.fullname = p3dConfig.Attribute('display_name')
                         self.fullname = p3dConfig.Attribute('display_name')
+        else:
+            Installer.notify.warning("No p3d_info.xml was found in .p3d archive.")
+
+        mf.close()
+
+        if not self.hostUrl:
+            self.hostUrl = PandaSystem.getPackageHostUrl()
+            if not self.hostUrl:
+                self.hostUrl = self.standalone.host.hostUrl
+            Installer.notify.warning("No host URL was specified by .p3d archive.  Falling back to %s" % (self.hostUrl))
 
 
         if not self.fullname:
         if not self.fullname:
             self.fullname = self.shortname
             self.fullname = self.shortname
 
 
+        self.tempDir = Filename.temporary("", self.shortname, "") + "/"
+        self.tempDir.makeDir()
+        self.__tempRoots = {}
+
+        if self.extracts:
+            # Copy .p3d to a temporary file so we can remove the extracts.
+            p3dfile = Filename(self.tempDir, self.p3dFilename.getBasename())
+            shutil.copyfile(self.p3dFilename.toOsSpecific(), p3dfile.toOsSpecific())
+            mf = Multifile()
+            if not mf.openReadWrite(p3dfile):
+                Installer.notify.error("Failure to open %s for writing." % (p3dfile))
+
+            # We don't really need this silly thing when embedding, anyway.
+            mf.setHeaderPrefix("")
+
+            for fn in self.extracts:
+                if not mf.removeSubfile(fn):
+                    Installer.notify.error("Failure to remove %s from multifile." % (p3dfile))
+
+            mf.repack()
+            mf.close()
+
+        self.standalone = Standalone(p3dfile, tokens)
+
     def __del__(self):
     def __del__(self):
         try:
         try:
             appRunner.rmtree(self.tempDir)
             appRunner.rmtree(self.tempDir)
@@ -533,6 +574,22 @@ class Installer:
         if not self.includeRequires:
         if not self.includeRequires:
             return
             return
 
 
+        # Write out the extracts from the original .p3d.
+        if self.extracts:
+            mf = Multifile()
+            if not mf.openRead(self.p3dFilename):
+                Installer.notify.error("Failed to open .p3d archive: %s" % (filename))
+
+            for filename in self.extracts:
+                i = mf.findSubfile(filename)
+                if i < 0:
+                    Installer.notify.error("Cannot find extract in .p3d archive: %s" % (filename))
+                    continue
+
+                if not mf.extractSubfile(i, Filename(hostDir, filename)):
+                    Installer.notify.error("Failed to extract file from .p3d archive: %s" % (filename))
+            mf.close()
+
         pkgTree = PackageTree(platform, hostDir, self.hostUrl)
         pkgTree = PackageTree(platform, hostDir, self.hostUrl)
         pkgTree.installPackage("images", None, self.standalone.host.hostUrl)
         pkgTree.installPackage("images", None, self.standalone.host.hostUrl)
 
 
@@ -618,6 +675,9 @@ class Installer:
         if len(platforms) == 0:
         if len(platforms) == 0:
             Installer.notify.warning("No platforms found to build for!")
             Installer.notify.warning("No platforms found to build for!")
 
 
+        if 'win32' in platforms and 'win_i386' in platforms:
+            platforms.remove('win32')
+
         outputDir = Filename(outputDir + "/")
         outputDir = Filename(outputDir + "/")
         outputDir.makeDir()
         outputDir.makeDir()
         for platform in platforms:
         for platform in platforms:
@@ -660,7 +720,8 @@ class Installer:
 
 
         Filename(tempdir, "usr/bin/").makeDir()
         Filename(tempdir, "usr/bin/").makeDir()
         if self.includeRequires:
         if self.includeRequires:
-            extraTokens = {"host_dir" : "/usr/lib/" + self.shortname.lower()}
+            extraTokens = {"host_dir" : "/usr/lib/" + self.shortname.lower(),
+                           "start_dir" : "/usr/lib/" + self.shortname.lower()}
         else:
         else:
             extraTokens = {}
             extraTokens = {}
         self.standalone.build(Filename(tempdir, "usr/bin/" + self.shortname.lower()), platform, extraTokens)
         self.standalone.build(Filename(tempdir, "usr/bin/" + self.shortname.lower()), platform, extraTokens)
@@ -712,7 +773,7 @@ class Installer:
         print >>desktop, "Type=Application"
         print >>desktop, "Type=Application"
         desktop.close()
         desktop.close()
 
 
-        if self.includeRequires:
+        if self.includeRequires or self.extracts:
             hostDir = Filename(tempdir, "usr/lib/%s/" % self.shortname.lower())
             hostDir = Filename(tempdir, "usr/lib/%s/" % self.shortname.lower())
             hostDir.makeDir()
             hostDir.makeDir()
             self.installPackagesInto(hostDir, platform)
             self.installPackagesInto(hostDir, platform)
@@ -742,16 +803,18 @@ class Installer:
         tempdir, totsize = self.__buildTempLinux(platform)
         tempdir, totsize = self.__buildTempLinux(platform)
 
 
         # Create a control file in memory.
         # Create a control file in memory.
-        controlfile = StringIO()
-        print >>controlfile, "Package: %s" % self.shortname.lower()
-        print >>controlfile, "Version: %s" % self.version
-        print >>controlfile, "Maintainer: %s <%s>" % (self.authorname, self.authoremail)
-        print >>controlfile, "Section: games"
-        print >>controlfile, "Priority: optional"
-        print >>controlfile, "Architecture: %s" % arch
-        print >>controlfile, "Installed-Size: %d" % -(-totsize / 1024)
-        print >>controlfile, "Description: %s" % self.fullname
-        print >>controlfile, "Depends: libc6, libgcc1, libstdc++6, libx11-6"
+        controlfile = BytesIO()
+        cout = TextIOWrapper(controlfile, encoding='utf-8', newline='')
+        cout.write(u"Package: %s\n" % self.shortname.lower())
+        cout.write(u"Version: %s\n" % self.version)
+        cout.write(u"Maintainer: %s <%s>\n" % (self.authorname, self.authoremail))
+        cout.write(u"Section: games\n")
+        cout.write(u"Priority: optional\n")
+        cout.write(u"Architecture: %s\n" % arch)
+        cout.write(u"Installed-Size: %d\n" % -(-totsize // 1024))
+        cout.write(u"Description: %s\n" % self.fullname)
+        cout.write(u"Depends: libc6, libgcc1, libstdc++6, libx11-6\n")
+        cout.flush()
         controlinfo = TarInfoRoot("control")
         controlinfo = TarInfoRoot("control")
         controlinfo.mtime = modtime
         controlinfo.mtime = modtime
         controlinfo.size = controlfile.tell()
         controlinfo.size = controlfile.tell()
@@ -762,33 +825,43 @@ class Installer:
         if output.exists():
         if output.exists():
             output.unlink()
             output.unlink()
         debfile = open(output.toOsSpecific(), "wb")
         debfile = open(output.toOsSpecific(), "wb")
-        debfile.write("!<arch>\x0A")
-        debfile.write("debian-binary   %-12lu0     0     100644  %-10ld\x60\x0A" % (modtime, 4))
-        debfile.write("2.0\x0A")
-
-        # Write the control.tar.gz to the archive.
-        debfile.write("control.tar.gz  %-12lu0     0     100644  %-10ld\x60\x0A" % (modtime, 0))
+        debfile.write(b"!<arch>\x0A")
+        pad_mtime = str(modtime).encode().ljust(12, b' ')
+
+        # The first entry is a special file that marks it a .deb.
+        debfile.write(b"debian-binary   ")
+        debfile.write(pad_mtime)
+        debfile.write(b"0     0     100644  4         \x60\x0A")
+        debfile.write(b"2.0\x0A")
+
+        # Write the control.tar.gz to the archive.  We'll leave the
+        # size 0 for now, and go back and fill it in later.
+        debfile.write(b"control.tar.gz  ")
+        debfile.write(pad_mtime)
+        debfile.write(b"0     0     100644  0         \x60\x0A")
         ctaroffs = debfile.tell()
         ctaroffs = debfile.tell()
         ctarfile = tarfile.open("control.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         ctarfile = tarfile.open("control.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         ctarfile.addfile(controlinfo, controlfile)
         ctarfile.addfile(controlinfo, controlfile)
         ctarfile.close()
         ctarfile.close()
         ctarsize = debfile.tell() - ctaroffs
         ctarsize = debfile.tell() - ctaroffs
-        if (ctarsize & 1): debfile.write("\x0A")
+        if (ctarsize & 1): debfile.write(b"\x0A")
 
 
-        # Write the data.tar.gz to the archive.
-        debfile.write("data.tar.gz     %-12lu0     0     100644  %-10ld\x60\x0A" % (modtime, 0))
+        # Write the data.tar.gz to the archive.  Again, leave size 0.
+        debfile.write(b"data.tar.gz     ")
+        debfile.write(pad_mtime)
+        debfile.write(b"0     0     100644  0         \x60\x0A")
         dtaroffs = debfile.tell()
         dtaroffs = debfile.tell()
         dtarfile = tarfile.open("data.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         dtarfile = tarfile.open("data.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         dtarfile.add(Filename(tempdir, "usr").toOsSpecific(), "/usr")
         dtarfile.add(Filename(tempdir, "usr").toOsSpecific(), "/usr")
         dtarfile.close()
         dtarfile.close()
         dtarsize = debfile.tell() - dtaroffs
         dtarsize = debfile.tell() - dtaroffs
-        if (dtarsize & 1): debfile.write("\x0A")
+        if (dtarsize & 1): debfile.write(b"\x0A")
 
 
         # Write the correct sizes of the archives.
         # Write the correct sizes of the archives.
         debfile.seek(ctaroffs - 12)
         debfile.seek(ctaroffs - 12)
-        debfile.write("%-10ld" % ctarsize)
+        debfile.write(str(ctarsize).encode().ljust(10, b' '))
         debfile.seek(dtaroffs - 12)
         debfile.seek(dtaroffs - 12)
-        debfile.write("%-10ld" % dtarsize)
+        debfile.write(str(dtarsize).encode().ljust(10, b' '))
 
 
         debfile.close()
         debfile.close()
 
 
@@ -815,18 +888,20 @@ class Installer:
         tempdir, totsize = self.__buildTempLinux(platform)
         tempdir, totsize = self.__buildTempLinux(platform)
 
 
         # Create a pkginfo file in memory.
         # Create a pkginfo file in memory.
-        pkginfo = StringIO()
-        print >>pkginfo, "# Generated using pdeploy"
-        print >>pkginfo, "# %s" % time.ctime(modtime)
-        print >>pkginfo, "pkgname = %s" % self.shortname.lower()
-        print >>pkginfo, "pkgver = %s" % pkgver
-        print >>pkginfo, "pkgdesc = %s" % self.fullname
-        print >>pkginfo, "builddate = %s" % modtime
-        print >>pkginfo, "packager = %s <%s>" % (self.authorname, self.authoremail)
-        print >>pkginfo, "size = %d" % totsize
-        print >>pkginfo, "arch = %s" % arch
+        pkginfo = BytesIO()
+        pout = TextIOWrapper(pkginfo, encoding='utf-8', newline='')
+        pout.write(u"# Generated using pdeploy\n")
+        pout.write(u"# %s\n" % time.ctime(modtime))
+        pout.write(u"pkgname = %s\n" % self.shortname.lower())
+        pout.write(u"pkgver = %s\n" % pkgver)
+        pout.write(u"pkgdesc = %s\n" % self.fullname)
+        pout.write(u"builddate = %s\n" % modtime)
+        pout.write(u"packager = %s <%s>\n" % (self.authorname, self.authoremail))
+        pout.write(u"size = %d\n" % totsize)
+        pout.write(u"arch = %s\n" % arch)
         if self.licensename != "":
         if self.licensename != "":
-            print >>pkginfo, "license = %s" % self.licensename
+            pout.write(u"license = %s\n" % self.licensename)
+        pout.flush()
         pkginfoinfo = TarInfoRoot(".PKGINFO")
         pkginfoinfo = TarInfoRoot(".PKGINFO")
         pkginfoinfo.mtime = modtime
         pkginfoinfo.mtime = modtime
         pkginfoinfo.size = pkginfo.tell()
         pkginfoinfo.size = pkginfo.tell()
@@ -853,7 +928,7 @@ class Installer:
         exefile = Filename(output, "Contents/MacOS/" + self.shortname)
         exefile = Filename(output, "Contents/MacOS/" + self.shortname)
         exefile.makeDir()
         exefile.makeDir()
         if self.includeRequires:
         if self.includeRequires:
-            extraTokens = {"host_dir" : "../Resources"}
+            extraTokens = {"host_dir": "../Resources", "start_dir": "../Resources"}
         else:
         else:
             extraTokens = {}
             extraTokens = {}
         self.standalone.build(exefile, platform, extraTokens)
         self.standalone.build(exefile, platform, extraTokens)
@@ -1064,7 +1139,7 @@ class Installer:
         exefile = Filename(Filename.getTempDirectory(), self.shortname + ".exe")
         exefile = Filename(Filename.getTempDirectory(), self.shortname + ".exe")
         exefile.unlink()
         exefile.unlink()
         if self.includeRequires:
         if self.includeRequires:
-            extraTokens = {"host_dir" : "."}
+            extraTokens = {"host_dir": ".", "start_dir": "."}
         else:
         else:
             extraTokens = {}
             extraTokens = {}
         self.standalone.build(exefile, platform, extraTokens)
         self.standalone.build(exefile, platform, extraTokens)

+ 2 - 0
direct/src/p3d/FileSpec.py

@@ -1,3 +1,5 @@
+__all__ = ["FileSpec"]
+
 import os
 import os
 import time
 import time
 from panda3d.core import Filename, HashVal, VirtualFileSystem
 from panda3d.core import Filename, HashVal, VirtualFileSystem

+ 19 - 21
direct/src/p3d/HostInfo.py

@@ -1,3 +1,5 @@
+__all__ = ["HostInfo"]
+
 from panda3d.core import HashVal, Filename, PandaSystem, DocumentSpec, Ramfile
 from panda3d.core import HashVal, Filename, PandaSystem, DocumentSpec, Ramfile
 from panda3d.core import HTTPChannel, ConfigVariableInt
 from panda3d.core import HTTPChannel, ConfigVariableInt
 from panda3d import core
 from panda3d import core
@@ -159,14 +161,14 @@ class HostInfo:
                 self.notify.info("Downloading contents file %s" % (request))
                 self.notify.info("Downloading contents file %s" % (request))
                 statusCode = None
                 statusCode = None
                 statusString = ''
                 statusString = ''
-                for attempt in range(ConfigVariableInt('contents-xml-dl-attempts', 3)):
+                for attempt in range(int(ConfigVariableInt('contents-xml-dl-attempts', 3))):
                     if attempt > 0:
                     if attempt > 0:
                         self.notify.info("Retrying (%s)..."%(attempt,))
                         self.notify.info("Retrying (%s)..."%(attempt,))
                     rf = Ramfile()
                     rf = Ramfile()
                     channel = http.makeChannel(False)
                     channel = http.makeChannel(False)
                     channel.getDocument(request)
                     channel.getDocument(request)
                     if channel.downloadToRam(rf):
                     if channel.downloadToRam(rf):
-                        self.notify.warning("Successfully downloaded %s" % (url,))
+                        self.notify.info("Successfully downloaded %s" % (url,))
                         break
                         break
                     else:
                     else:
                         rf = None
                         rf = None
@@ -367,7 +369,7 @@ class HostInfo:
             assert self.hostDir
             assert self.hostDir
             self.__findHostXmlForHostDir(xcontents)
             self.__findHostXmlForHostDir(xcontents)
 
 
-        if not self.hostDir:
+        if self.rootDir and not self.hostDir:
             self.hostDir = self.__determineHostDir(None, self.hostUrl)
             self.hostDir = self.__determineHostDir(None, self.hostUrl)
 
 
         # Get the list of packages available for download and/or import.
         # Get the list of packages available for download and/or import.
@@ -401,7 +403,7 @@ class HostInfo:
         self.hasContentsFile = True
         self.hasContentsFile = True
 
 
         # Now save the contents.xml file into the standard location.
         # Now save the contents.xml file into the standard location.
-        if not self.appRunner or self.appRunner.verifyContents != self.appRunner.P3DVCNever:
+        if self.appRunner and self.appRunner.verifyContents != self.appRunner.P3DVCNever:
             assert self.hostDir
             assert self.hostDir
             filename = Filename(self.hostDir, 'contents.xml')
             filename = Filename(self.hostDir, 'contents.xml')
             filename.makeDir()
             filename.makeDir()
@@ -474,7 +476,7 @@ class HostInfo:
             self.descriptiveName = descriptiveName
             self.descriptiveName = descriptiveName
 
 
         hostDirBasename = xhost.Attribute('host_dir')
         hostDirBasename = xhost.Attribute('host_dir')
-        if not self.hostDir:
+        if self.rootDir and not self.hostDir:
             self.hostDir = self.__determineHostDir(hostDirBasename, self.hostUrl)
             self.hostDir = self.__determineHostDir(hostDirBasename, self.hostUrl)
 
 
         # Get the "download" URL, which is the source from which we
         # Get the "download" URL, which is the source from which we
@@ -511,17 +513,15 @@ class HostInfo:
         PackageInfo, returns it. """
         PackageInfo, returns it. """
 
 
         if not platform:
         if not platform:
-            # Ensure that we're on the same page with non-specified
-            # platforms.  We always use None, not empty string.
             platform = None
             platform = None
 
 
-        platforms = self.packages.setdefault((name, version), {})
-        package = platforms.get(platform, None)
+        platforms = self.packages.setdefault((name, version or ""), {})
+        package = platforms.get("", None)
         if not package:
         if not package:
             package = PackageInfo(self, name, version, platform = platform,
             package = PackageInfo(self, name, version, platform = platform,
                                   solo = solo, asMirror = self.asMirror,
                                   solo = solo, asMirror = self.asMirror,
                                   perPlatform = perPlatform)
                                   perPlatform = perPlatform)
-            platforms[platform] = package
+            platforms[platform or ""] = package
 
 
         return package
         return package
 
 
@@ -531,12 +531,12 @@ class HostInfo:
         platform, if one is provided by this host, or None if not. """
         platform, if one is provided by this host, or None if not. """
 
 
         assert self.hasContentsFile
         assert self.hasContentsFile
-        platforms = self.packages.get((name, version or None), {})
+        platforms = self.packages.get((name, version or ""), {})
 
 
-        if platform is not None:
+        if platform:
             # In this case, we are looking for a specific platform
             # In this case, we are looking for a specific platform
             # only.
             # only.
-            return platforms.get(platform or None, None)
+            return platforms.get(platform, None)
 
 
         # We are looking for one matching the current runtime
         # We are looking for one matching the current runtime
         # platform.  First, look for a package matching the current
         # platform.  First, look for a package matching the current
@@ -545,7 +545,7 @@ class HostInfo:
 
 
         # If not found, look for one matching no particular platform.
         # If not found, look for one matching no particular platform.
         if not package:
         if not package:
-            package = platforms.get(None, None)
+            package = platforms.get("", None)
 
 
         return package
         return package
 
 
@@ -561,7 +561,7 @@ class HostInfo:
             if name and pn != name:
             if name and pn != name:
                 continue
                 continue
 
 
-            if platform is None:
+            if not platform:
                 for p2 in platforms:
                 for p2 in platforms:
                     package = self.getPackage(pn, version, platform = p2)
                     package = self.getPackage(pn, version, platform = p2)
                     if package:
                     if package:
@@ -579,14 +579,12 @@ class HostInfo:
 
 
         result = []
         result = []
 
 
-        items = self.packages.items()
-        items.sort()
+        items = sorted(self.packages.items())
         for key, platforms in items:
         for key, platforms in items:
             if self.perPlatform or includeAllPlatforms:
             if self.perPlatform or includeAllPlatforms:
                 # If we maintain a different answer per platform,
                 # If we maintain a different answer per platform,
                 # return all of them.
                 # return all of them.
-                pitems = platforms.items()
-                pitems.sort()
+                pitems = sorted(platforms.items())
                 for pkey, package in pitems:
                 for pkey, package in pitems:
                     result.append(package)
                     result.append(package)
             else:
             else:
@@ -595,7 +593,7 @@ class HostInfo:
                 # current platform, or no particular platform.
                 # current platform, or no particular platform.
                 package = platforms.get(PandaSystem.getPlatform(), None)
                 package = platforms.get(PandaSystem.getPlatform(), None)
                 if not package:
                 if not package:
-                    package = platforms.get(None, None)
+                    package = platforms.get("", None)
 
 
                 if package:
                 if package:
                     result.append(package)
                     result.append(package)
@@ -699,7 +697,7 @@ class HostInfo:
 
 
             # If we successfully got a hostname, we don't really need the
             # If we successfully got a hostname, we don't really need the
             # full hash.  We'll keep half of it.
             # full hash.  We'll keep half of it.
-            keepHash = keepHash / 2;
+            keepHash = keepHash // 2
 
 
         md = HashVal()
         md = HashVal()
         md.hashString(hostUrl)
         md.hashString(hostUrl)

+ 2 - 0
direct/src/p3d/InstalledHostData.py

@@ -1,3 +1,5 @@
+__all__ = ["InstalledHostData"]
+
 from panda3d.core import URLSpec
 from panda3d.core import URLSpec
 
 
 class InstalledHostData:
 class InstalledHostData:

+ 2 - 0
direct/src/p3d/InstalledPackageData.py

@@ -1,3 +1,5 @@
+__all__ = ["InstalledPackageData"]
+
 class InstalledPackageData:
 class InstalledPackageData:
     """ A list of instances of this class is maintained by
     """ A list of instances of this class is maintained by
     InstalledHostData (which is in turn returned by
     InstalledHostData (which is in turn returned by

+ 2 - 0
direct/src/p3d/JavaScript.py

@@ -2,6 +2,8 @@
 useful when writing code that integrates with JavaScript, especially
 useful when writing code that integrates with JavaScript, especially
 code that runs in a browser via the web plugin. """
 code that runs in a browser via the web plugin. """
 
 
+__all__ = ["UndefinedObject", "Undefined", "ConcreteStruct", "BrowserObject", "MethodWrapper"]
+
 import types
 import types
 
 
 class UndefinedObject:
 class UndefinedObject:

+ 7 - 4
direct/src/p3d/PackageInfo.py

@@ -1,4 +1,6 @@
-from panda3d.core import Filename, URLSpec, DocumentSpec, Ramfile, Multifile, Decompressor, EUOk, EUSuccess, VirtualFileSystem, Thread, getModelPath, ExecutionEnvironment, PStatCollector, TiXmlDocument, TiXmlDeclaration, TiXmlElement
+__all__ = ["PackageInfo"]
+
+from panda3d.core import Filename, DocumentSpec, Multifile, Decompressor, EUOk, EUSuccess, VirtualFileSystem, Thread, getModelPath, ExecutionEnvironment, PStatCollector, TiXmlDocument, TiXmlDeclaration, TiXmlElement
 import panda3d.core as core
 import panda3d.core as core
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.ScanDirectoryNode import ScanDirectoryNode
 from direct.p3d.ScanDirectoryNode import ScanDirectoryNode
@@ -275,7 +277,7 @@ class PackageInfo:
             # We've already got one.
             # We've already got one.
             yield self.stepComplete; return
             yield self.stepComplete; return
 
 
-        if self.host.appRunner and self.host.appRunner.verifyContents != self.host.appRunner.P3DVCNever:
+        if not self.host.appRunner or self.host.appRunner.verifyContents != self.host.appRunner.P3DVCNever:
             # We're allowed to download it.
             # We're allowed to download it.
             self.http = http
             self.http = http
 
 
@@ -521,7 +523,8 @@ class PackageInfo:
 
 
         # In case of unexpected failures on the internet, we will retry
         # In case of unexpected failures on the internet, we will retry
         # the full download instead of just giving up.
         # the full download instead of just giving up.
-        for retry in range(core.ConfigVariableInt('package-full-dl-retries', 1)):
+        retries = core.ConfigVariableInt('package-full-dl-retries', 1).getValue()
+        for retry in range(retries):
             self.installPlans.append(planB[:])
             self.installPlans.append(planB[:])
 
 
         pc.stop()
         pc.stop()
@@ -1149,7 +1152,7 @@ class PackageInfo:
         thisDir = ScanDirectoryNode(self.getPackageDir(), ignoreUsageXml = True)
         thisDir = ScanDirectoryNode(self.getPackageDir(), ignoreUsageXml = True)
         diskSpace = thisDir.getTotalSize()
         diskSpace = thisDir.getTotalSize()
         self.notify.info("Package %s uses %s MB" % (
         self.notify.info("Package %s uses %s MB" % (
-            self.packageName, (diskSpace + 524288) / 1048576))
+            self.packageName, (diskSpace + 524288) // 1048576))
         return diskSpace
         return diskSpace
 
 
     def markUsed(self):
     def markUsed(self):

+ 2 - 0
direct/src/p3d/PackageInstaller.py

@@ -1,3 +1,5 @@
+__all__ = ["PackageInstaller"]
+
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.stdpy.threading import Lock, RLock
 from direct.stdpy.threading import Lock, RLock
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase.MessengerGlobal import messenger

+ 2 - 1
direct/src/p3d/PackageMerger.py

@@ -1,8 +1,9 @@
+__all__ = ["PackageMerger", "PackageMergerError"]
+
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.SeqValue import SeqValue
 from direct.p3d.SeqValue import SeqValue
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.directnotify.DirectNotifyGlobal import *
 from panda3d.core import *
 from panda3d.core import *
-import copy
 import shutil
 import shutil
 import os
 import os
 
 

+ 150 - 65
direct/src/p3d/Packager.py

@@ -3,19 +3,20 @@ within a Panda3D Multifile, which can be easily be downloaded and/or
 patched onto a client machine, for the purpose of running a large
 patched onto a client machine, for the purpose of running a large
 application. """
 application. """
 
 
+__all__ = ["Packager", "PackagerError", "OutsideOfPackageError", "ArgumentError"]
+
 # Important to import panda3d first, to avoid naming conflicts with
 # Important to import panda3d first, to avoid naming conflicts with
 # Python's "string" and "Loader" names that are imported later.
 # Python's "string" and "Loader" names that are imported later.
 from panda3d.core import *
 from panda3d.core import *
 import sys
 import sys
 import os
 import os
 import glob
 import glob
-import marshal
 import string
 import string
 import types
 import types
 import getpass
 import getpass
-import platform
 import struct
 import struct
 import subprocess
 import subprocess
+import copy
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.SeqValue import SeqValue
 from direct.p3d.SeqValue import SeqValue
 from direct.showbase import Loader
 from direct.showbase import Loader
@@ -185,7 +186,7 @@ class Packager:
         def getKey(self):
         def getKey(self):
             """ Returns a tuple used for sorting the PackageEntry
             """ Returns a tuple used for sorting the PackageEntry
             objects uniquely per package. """
             objects uniquely per package. """
-            return (self.packageName, self.platform, self.version)
+            return (self.packageName, self.platform or "", self.version or "")
 
 
         def fromFile(self, packageName, platform, version, solo, perPlatform,
         def fromFile(self, packageName, platform, version, solo, perPlatform,
                      installDir, descFilename, importDescFilename):
                      installDir, descFilename, importDescFilename):
@@ -299,8 +300,7 @@ class Packager:
                 xhost.InsertEndChild(xmirror)
                 xhost.InsertEndChild(xmirror)
 
 
             if packager:
             if packager:
-                altHosts = self.altHosts.items()
-                altHosts.sort()
+                altHosts = sorted(self.altHosts.items())
                 for keyword, alt in altHosts:
                 for keyword, alt in altHosts:
                     he = packager.hosts.get(alt, None)
                     he = packager.hosts.get(alt, None)
                     if he:
                     if he:
@@ -372,9 +372,15 @@ class Packager:
             self.requiredFilenames = []
             self.requiredFilenames = []
             self.requiredModules = []
             self.requiredModules = []
 
 
+            # A list of required packages that were missing.
+            self.missingPackages = []
+
             # This records the current list of modules we have added so
             # This records the current list of modules we have added so
             # far.
             # far.
             self.freezer = FreezeTool.Freezer(platform = self.packager.platform)
             self.freezer = FreezeTool.Freezer(platform = self.packager.platform)
+            
+            # Map of extensions to files to number (ignored by dir)
+            self.ignoredDirFiles = {}
 
 
         def close(self):
         def close(self):
             """ Writes out the contents of the current package.  Returns True
             """ Writes out the contents of the current package.  Returns True
@@ -385,6 +391,12 @@ class Packager:
                 message = 'Cannot generate packages without an installDir; use -i'
                 message = 'Cannot generate packages without an installDir; use -i'
                 raise PackagerError, message
                 raise PackagerError, message
 
 
+            if self.ignoredDirFiles:
+                exts = sorted(self.ignoredDirFiles.keys())
+                total = sum([x for x in self.ignoredDirFiles.values()])
+                self.notify.warning("excluded %s files not marked for inclusion: %s" \
+                                    % (total, ", ".join(["'" + ext + "'" for ext in exts])))
+                
             if not self.host:
             if not self.host:
                 self.host = self.packager.host
                 self.host = self.packager.host
 
 
@@ -454,7 +466,7 @@ class Packager:
             if self.p3dApplication:
             if self.p3dApplication:
                 allowPythonDev = self.configs.get('allow_python_dev', 0)
                 allowPythonDev = self.configs.get('allow_python_dev', 0)
                 if int(allowPythonDev):
                 if int(allowPythonDev):
-                    print "\n*** Generating %s.p3d with allow_python_dev enabled ***\n" % (self.packageName)
+                    print("\n*** Generating %s.p3d with allow_python_dev enabled ***\n" % (self.packageName))
 
 
             return result
             return result
 
 
@@ -485,6 +497,12 @@ class Packager:
             as a true package.  Either is implemented with a
             as a true package.  Either is implemented with a
             Multifile. """
             Multifile. """
 
 
+            if self.missingPackages:
+                missing = ', '.join([name for name, version in self.missingPackages])
+                self.notify.warning("Cannot build package %s due to missing dependencies: %s" % (self.packageName, missing))
+                self.cleanup()
+                return False
+
             self.multifile = Multifile()
             self.multifile = Multifile()
 
 
             # Write the multifile to a temporary filename until we
             # Write the multifile to a temporary filename until we
@@ -570,8 +588,7 @@ class Packager:
 
 
             # Add known module names.
             # Add known module names.
             self.moduleNames = {}
             self.moduleNames = {}
-            modules = self.freezer.modules.items()
-            modules.sort()
+            modules = sorted(self.freezer.modules.items())
             for newName, mdef in modules:
             for newName, mdef in modules:
                 if mdef.guess:
                 if mdef.guess:
                     # Not really a module.
                     # Not really a module.
@@ -702,7 +719,7 @@ class Packager:
             self.packageDesc = packageDir + self.packageDesc
             self.packageDesc = packageDir + self.packageDesc
             self.packageImportDesc = packageDir + self.packageImportDesc
             self.packageImportDesc = packageDir + self.packageImportDesc
 
 
-            print "Generating %s" % (self.packageFilename)
+            print("Generating %s" % (self.packageFilename))
 
 
             if self.p3dApplication:
             if self.p3dApplication:
                 self.packageFullpath = Filename(self.packager.p3dInstallDir, self.packageFilename)
                 self.packageFullpath = Filename(self.packager.p3dInstallDir, self.packageFilename)
@@ -820,6 +837,14 @@ class Packager:
             self.packager.contents[pe.getKey()] = pe
             self.packager.contents[pe.getKey()] = pe
             self.packager.contentsChanged = True
             self.packager.contentsChanged = True
 
 
+            # Hack for coreapi package, to preserve backward compatibility
+            # with old versions of the runtime, which still called the
+            # 32-bit Windows platform "win32".
+            if self.packageName == "coreapi" and self.platform == "win_i386":
+                pe2 = copy.copy(pe)
+                pe2.platform = "win32"
+                self.packager.contents[pe2.getKey()] = pe2
+
             self.cleanup()
             self.cleanup()
             return True
             return True
 
 
@@ -1232,13 +1257,13 @@ class Packager:
                 elf.close()
                 elf.close()
                 return None
                 return None
 
 
-            if not ident.startswith("\177ELF"):
+            if not ident.startswith(b"\177ELF"):
                 # No elf magic!  Beware of orcs.
                 # No elf magic!  Beware of orcs.
                 return None
                 return None
 
 
             # Make sure we read in the correct endianness and integer size
             # Make sure we read in the correct endianness and integer size
-            byteOrder = "<>"[ord(ident[5]) - 1]
-            elfClass = ord(ident[4]) - 1 # 0 = 32-bits, 1 = 64-bits
+            byteOrder = "<>"[ord(ident[5:6]) - 1]
+            elfClass = ord(ident[4:5]) - 1 # 0 = 32-bits, 1 = 64-bits
             headerStruct = byteOrder + ("HHIIIIIHHHHHH", "HHIQQQIHHHHHH")[elfClass]
             headerStruct = byteOrder + ("HHIIIIIHHHHHH", "HHIQQQIHHHHHH")[elfClass]
             sectionStruct = byteOrder + ("4xI8xIII8xI", "4xI16xQQI12xQ")[elfClass]
             sectionStruct = byteOrder + ("4xI8xIII8xI", "4xI16xQQI12xQ")[elfClass]
             dynamicStruct = byteOrder + ("iI", "qQ")[elfClass]
             dynamicStruct = byteOrder + ("iI", "qQ")[elfClass]
@@ -1272,17 +1297,17 @@ class Packager:
                 elf.seek(offset)
                 elf.seek(offset)
                 data = elf.read(entsize)
                 data = elf.read(entsize)
                 tag, val = struct.unpack_from(dynamicStruct, data)
                 tag, val = struct.unpack_from(dynamicStruct, data)
-                newSectionData = ""
+                newSectionData = b""
                 startReplace = None
                 startReplace = None
                 pad = 0
                 pad = 0
 
 
                 # Read tags until we find a NULL tag.
                 # Read tags until we find a NULL tag.
                 while tag != 0:
                 while tag != 0:
                     if tag == 1: # A NEEDED entry.  Read it from the string table.
                     if tag == 1: # A NEEDED entry.  Read it from the string table.
-                        filenames.append(stringTables[link][val : stringTables[link].find('\0', val)])
+                        filenames.append(stringTables[link][val : stringTables[link].find(b'\0', val)])
 
 
                     elif tag == 15 or tag == 29:
                     elif tag == 15 or tag == 29:
-                        rpath += stringTables[link][val : stringTables[link].find('\0', val)].split(':')
+                        rpath += stringTables[link][val : stringTables[link].find(b'\0', val)].split(b':')
                         # An RPATH or RUNPATH entry.
                         # An RPATH or RUNPATH entry.
                         if not startReplace:
                         if not startReplace:
                             startReplace = elf.tell() - entsize
                             startReplace = elf.tell() - entsize
@@ -1296,7 +1321,7 @@ class Packager:
                     tag, val = struct.unpack_from(dynamicStruct, data)
                     tag, val = struct.unpack_from(dynamicStruct, data)
 
 
                 if startReplace is not None:
                 if startReplace is not None:
-                    newSectionData += data + ("\0" * pad)
+                    newSectionData += data + (b"\0" * pad)
                     rewriteSections.append((startReplace, newSectionData))
                     rewriteSections.append((startReplace, newSectionData))
             elf.close()
             elf.close()
 
 
@@ -1329,7 +1354,7 @@ class Packager:
             for offset, data in rewriteSections:
             for offset, data in rewriteSections:
                 elf.seek(offset)
                 elf.seek(offset)
                 elf.write(data)
                 elf.write(data)
-            elf.write("\0" * pad)
+            elf.write(b"\0" * pad)
             elf.close()
             elf.close()
             return filenames
             return filenames
 
 
@@ -1468,6 +1493,10 @@ class Packager:
                     xhost = he.makeXml(packager = self.packager)
                     xhost = he.makeXml(packager = self.packager)
                     xpackage.InsertEndChild(xhost)
                     xpackage.InsertEndChild(xhost)
 
 
+            self.extracts.sort()
+            for name, xextract in self.extracts:
+                xpackage.InsertEndChild(xextract)
+
             doc.InsertEndChild(xpackage)
             doc.InsertEndChild(xpackage)
 
 
             # Write the xml file to a temporary file on disk, so we
             # Write the xml file to a temporary file on disk, so we
@@ -1813,7 +1842,10 @@ class Packager:
                         self.notify.warning(message)
                         self.notify.warning(message)
                     return
                     return
 
 
-            self.freezer.addModule(moduleName, filename = file.filename)
+            if file.text:
+                self.freezer.addModule(moduleName, filename = file.filename, text = file.text)
+            else:
+                self.freezer.addModule(moduleName, filename = file.filename)
 
 
         def addEggFile(self, file):
         def addEggFile(self, file):
             # Precompile egg files to bam's.
             # Precompile egg files to bam's.
@@ -2161,8 +2193,10 @@ class Packager:
                     ext = Filename(lowerName).getExtension()
                     ext = Filename(lowerName).getExtension()
                     if ext not in self.packager.nonuniqueExtensions:
                     if ext not in self.packager.nonuniqueExtensions:
                         self.skipFilenames[lowerName] = True
                         self.skipFilenames[lowerName] = True
+
                 for moduleName, mdef in package.moduleNames.items():
                 for moduleName, mdef in package.moduleNames.items():
-                    self.skipModules[moduleName] = mdef
+                    if not mdef.exclude:
+                        self.skipModules[moduleName] = mdef
 
 
     # Packager constructor
     # Packager constructor
     def __init__(self, platform = None):
     def __init__(self, platform = None):
@@ -2185,6 +2219,9 @@ class Packager:
         # ignoring any request to specify a particular download host,
         # ignoring any request to specify a particular download host,
         # e.g. for testing and development.
         # e.g. for testing and development.
         self.ignoreSetHost = False
         self.ignoreSetHost = False
+        
+        # Set this to true to verbosely log files ignored by dir().
+        self.verbosePrint = False
 
 
         # This will be appended to the basename of any .p3d package,
         # This will be appended to the basename of any .p3d package,
         # before the .p3d extension.
         # before the .p3d extension.
@@ -2333,7 +2370,7 @@ class Packager:
 
 
         # Binary files that are copied (and compressed) without
         # Binary files that are copied (and compressed) without
         # processing.
         # processing.
-        self.binaryExtensions = [ 'ttf', 'TTF', 'mid', 'ico' ]
+        self.binaryExtensions = [ 'ttf', 'TTF', 'mid', 'ico', 'cur' ]
 
 
         # Files that can have an existence in multiple different
         # Files that can have an existence in multiple different
         # packages simultaneously without conflict.
         # packages simultaneously without conflict.
@@ -2373,7 +2410,7 @@ class Packager:
                 }
                 }
 
 
         # Files that should be extracted to disk.
         # Files that should be extracted to disk.
-        self.extractExtensions = self.executableExtensions[:] + self.manifestExtensions[:] + [ 'ico' ]
+        self.extractExtensions = self.executableExtensions[:] + self.manifestExtensions[:] + [ 'ico', 'cur' ]
 
 
         # Files that indicate a platform dependency.
         # Files that indicate a platform dependency.
         self.platformSpecificExtensions = self.executableExtensions[:]
         self.platformSpecificExtensions = self.executableExtensions[:]
@@ -2390,6 +2427,14 @@ class Packager:
         # should be added exactly byte-for-byte as they are.
         # should be added exactly byte-for-byte as they are.
         self.unprocessedExtensions = []
         self.unprocessedExtensions = []
 
 
+        # Files for which warnings should be suppressed when they are
+        # not handled by dir()
+        self.suppressWarningForExtensions = ['', 'pyc', 'pyo', 
+                                             'p3d', 'pdef', 
+                                             'c', 'C', 'cxx', 'cpp', 'h', 'H',
+                                             'hpp', 'pp', 'I', 'pem', 'p12', 'crt',
+                                             'o', 'obj', 'a', 'lib', 'bc', 'll']
+         
         # System files that should never be packaged.  For
         # System files that should never be packaged.  For
         # case-insensitive filesystems (like Windows and OSX), put the
         # case-insensitive filesystems (like Windows and OSX), put the
         # lowercase filename here.  Case-sensitive filesystems should
         # lowercase filename here.  Case-sensitive filesystems should
@@ -2456,7 +2501,7 @@ class Packager:
         if not os.path.isfile('/sbin/ldconfig'):
         if not os.path.isfile('/sbin/ldconfig'):
             return False
             return False
 
 
-        handle = subprocess.Popen(['/sbin/ldconfig', '-p'], stdout=subprocess.PIPE)
+        handle = subprocess.Popen(['/sbin/ldconfig', '-p'], stdout=subprocess.PIPE, universal_newlines=True)
         out, err = handle.communicate()
         out, err = handle.communicate()
 
 
         if handle.returncode != 0:
         if handle.returncode != 0:
@@ -2617,12 +2662,20 @@ class Packager:
             if dirname.makeTrueCase():
             if dirname.makeTrueCase():
                 searchPath.appendDirectory(dirname)
                 searchPath.appendDirectory(dirname)
 
 
+    def _ensureExtensions(self):
+        self.knownExtensions = \
+            self.imageExtensions + \
+            self.modelExtensions + \
+            self.textExtensions + \
+            self.binaryExtensions + \
+            self.uncompressibleExtensions + \
+            self.unprocessedExtensions
 
 
     def setup(self):
     def setup(self):
         """ Call this method to initialize the class after filling in
         """ Call this method to initialize the class after filling in
         some of the values in the constructor. """
         some of the values in the constructor. """
 
 
-        self.knownExtensions = self.imageExtensions + self.modelExtensions + self.textExtensions + self.binaryExtensions + self.uncompressibleExtensions + self.unprocessedExtensions
+        self._ensureExtensions()
 
 
         self.currentPackage = None
         self.currentPackage = None
 
 
@@ -2710,11 +2763,15 @@ class Packager:
         # errors, and that the pdef file doesn't contain any really
         # errors, and that the pdef file doesn't contain any really
         # crazy Python code, all this will do is fill in the
         # crazy Python code, all this will do is fill in the
         # '__statements' list in the module scope.
         # '__statements' list in the module scope.
+        fn = packageDef.toOsSpecific()
+        f = open(fn)
+        code = compile(f.read(), fn, 'exec')
+        f.close()
 
 
         # It appears that having a separate globals and locals
         # It appears that having a separate globals and locals
         # dictionary causes problems with resolving symbols within a
         # dictionary causes problems with resolving symbols within a
         # class scope.  So, we just use one dictionary, the globals.
         # class scope.  So, we just use one dictionary, the globals.
-        execfile(packageDef.toOsSpecific(), globals)
+        exec(code, globals)
 
 
         packages = []
         packages = []
 
 
@@ -2979,10 +3036,10 @@ class Packager:
             # environment.
             # environment.
             return None
             return None
 
 
+        # Make sure we have a fresh version of the contents file.
         host = appRunner.getHost(hostUrl)
         host = appRunner.getHost(hostUrl)
-        if not host.readContentsFile():
-            if not host.downloadContentsFile(appRunner.http):
-                return None
+        if not host.downloadContentsFile(appRunner.http):
+            return None
 
 
         packageInfos = []
         packageInfos = []
         packageInfo = host.getPackage(packageName, version, platform = platform)
         packageInfo = host.getPackage(packageName, version, platform = platform)
@@ -3031,7 +3088,7 @@ class Packager:
         tuples = []
         tuples = []
         for package in packages:
         for package in packages:
             version = self.__makeVersionTuple(package.version)
             version = self.__makeVersionTuple(package.version)
-            tuples.append((version, file))
+            tuples.append((version, package))
         tuples.sort(reverse = True)
         tuples.sort(reverse = True)
 
 
         return [t[1] for t in tuples]
         return [t[1] for t in tuples]
@@ -3044,7 +3101,7 @@ class Packager:
         tuples = []
         tuples = []
         for package in packages:
         for package in packages:
             version = self.__makeVersionTuple(package.packageVersion)
             version = self.__makeVersionTuple(package.packageVersion)
-            tuples.append((version, file))
+            tuples.append((version, package))
         tuples.sort(reverse = True)
         tuples.sort(reverse = True)
 
 
         return [t[1] for t in tuples]
         return [t[1] for t in tuples]
@@ -3103,9 +3160,9 @@ class Packager:
         if panda1.version == panda2.version:
         if panda1.version == panda2.version:
             return True
             return True
 
 
-        print 'Rejecting package %s, version "%s": depends on %s, version "%s" instead of version "%s"' % (
+        print('Rejecting package %s, version "%s": depends on %s, version "%s" instead of version "%s"' % (
             package.packageName, package.version,
             package.packageName, package.version,
-            panda1.packageName, panda1.version, panda2.version)
+            panda1.packageName, panda1.version, panda2.version))
         return False
         return False
 
 
     def __findPackageInRequires(self, packageName, list):
     def __findPackageInRequires(self, packageName, list):
@@ -3188,7 +3245,9 @@ class Packager:
                                        requires = self.currentPackage.requires)
                                        requires = self.currentPackage.requires)
             if not package:
             if not package:
                 message = 'Unknown package %s, version "%s"' % (packageName, version)
                 message = 'Unknown package %s, version "%s"' % (packageName, version)
-                raise PackagerError, message
+                self.notify.warning(message)
+                self.currentPackage.missingPackages.append((packageName, pversion))
+                continue
 
 
             self.requirePackage(package)
             self.requirePackage(package)
 
 
@@ -3293,42 +3352,27 @@ class Packager:
         producing their own custom panda3d for download.  Should be
         producing their own custom panda3d for download.  Should be
         called before any other Python modules are named. """
         called before any other Python modules are named. """
 
 
-        # First, freeze just VFSImporter.py into its own
-        # _vfsimporter.pyd file.  This one is a special case, because
-        # we need this code in order to load python files from the
-        # Multifile, so this file can't itself be in the Multifile.
-
-        # This requires a bit of care, because we only want to freeze
-        # VFSImporter.py, and not any other part of direct.  We do
-        # also want panda3d/__init__.py, though, since it would
-        # otherwise be part of the multifile.
-        self.do_excludeModule('direct')
-
-        # Import the actual VFSImporter module to get its filename on
-        # disk.
-        from direct.showbase import VFSImporter
-        filename = Filename.fromOsSpecific(VFSImporter.__file__)
-
-        self.do_module('VFSImporter', filename = filename)
-        self.do_freeze('_vfsimporter', compileToExe = False)
+        # This module and all its dependencies come frozen into p3dpython.
+        # We should mark them as having already been added so that we don't
+        # add them again to the Multifile.
+        self.do_module('direct.showbase.VFSImporter')
+        self.currentPackage.freezer.done(addStartupModules=True)
+        self.currentPackage.freezer.writeCode(None)
+        self.currentPackage.addExtensionModules()
+        self.currentPackage.freezer.reset()
 
 
-        self.do_file('panda3d/core.pyd');
-
-        # Now that we're done freezing, explicitly add 'direct' to
-        # counteract the previous explicit excludeModule().
-        self.do_module('direct')
+        self.do_file('panda3d/_core.pyd', newDir='panda3d')
 
 
         # This is the key Python module that is imported at runtime to
         # This is the key Python module that is imported at runtime to
         # start an application running.
         # start an application running.
         self.do_module('direct.p3d.AppRunner')
         self.do_module('direct.p3d.AppRunner')
 
 
         # This is the main program that drives the runtime Python.  It
         # This is the main program that drives the runtime Python.  It
-        # is responsible for loading _vfsimporter.pyd, and then
-        # importing direct.p3d.AppRunner, to start an application
-        # running.  The program comes in two parts: an executable, and
-        # an associated dynamic library.  Note that the .exe and .dll
-        # extensions are automatically replaced with the appropriate
-        # platform-specific extensions.
+        # is responsible for importing direct.p3d.AppRunner to start an
+        # application running.  The program comes in two parts: an
+        # executable, and an associated dynamic library.  Note that the
+        # .exe and .dll extensions are automatically replaced with the
+        # appropriate platform-specific extensions.
 
 
         if self.platform.startswith('osx'):
         if self.platform.startswith('osx'):
             # On Mac, we package up a P3DPython.app bundle.  This
             # On Mac, we package up a P3DPython.app bundle.  This
@@ -3411,7 +3455,7 @@ class Packager:
                 freezer.addModule(moduleName, newName = newName)
                 freezer.addModule(moduleName, newName = newName)
             else:
             else:
                 freezer.modules[newName] = freezer.modules[moduleName]
                 freezer.modules[newName] = freezer.modules[moduleName]
-        freezer.done(compileToExe = compileToExe)
+        freezer.done(addStartupModules = compileToExe)
 
 
         dirname = ''
         dirname = ''
         basename = filename
         basename = filename
@@ -3604,6 +3648,43 @@ class Packager:
         filename = Filename(filename)
         filename = Filename(filename)
         self.currentPackage.excludeFile(filename)
         self.currentPackage.excludeFile(filename)
 
 
+
+    def do_includeExtensions(self, executableExtensions = None, extractExtensions = None, 
+                         imageExtensions = None, textExtensions = None, 
+                         uncompressibleExtensions = None, unprocessedExtensions = None,
+                         suppressWarningForExtensions = None):
+        """ Ensure that dir() will include files with the given extensions.
+        The extensions should not have '.' prefixes.
+        
+        All except 'suppressWarningForExtensions' allow the given kinds of files
+        to be packaged with their respective semantics (read the source).
+        
+        'suppressWarningForExtensions' lists extensions *expected* to be ignored, 
+        so no warnings will be emitted for them.
+        """
+        if executableExtensions:
+            self.executableExtensions += executableExtensions
+
+        if extractExtensions:
+            self.extractExtensions += extractExtensions
+
+        if imageExtensions:
+            self.imageExtensions += imageExtensions
+
+        if textExtensions:
+            self.textExtensions += textExtensions
+
+        if uncompressibleExtensions:
+            self.uncompressibleExtensions += uncompressibleExtensions
+
+        if unprocessedExtensions:
+            self.unprocessedExtensions += unprocessedExtensions
+
+        if suppressWarningForExtensions:
+            self.suppressWarningForExtensions += suppressWarningForExtensions
+
+        self._ensureExtensions()
+
     def do_dir(self, dirname, newDir = None, unprocessed = None):
     def do_dir(self, dirname, newDir = None, unprocessed = None):
 
 
         """ Adds the indicated directory hierarchy to the current
         """ Adds the indicated directory hierarchy to the current
@@ -3676,7 +3757,12 @@ class Packager:
                     filename.setBinary()
                     filename.setBinary()
                 self.currentPackage.addFile(filename, newName = newName,
                 self.currentPackage.addFile(filename, newName = newName,
                                             explicit = False, unprocessed = unprocessed)
                                             explicit = False, unprocessed = unprocessed)
-
+            elif not ext in self.suppressWarningForExtensions:
+                newCount = self.currentPackage.ignoredDirFiles.get(ext, 0) + 1
+                self.currentPackage.ignoredDirFiles[ext] = newCount
+                
+                if self.verbosePrint:
+                    self.notify.warning("ignoring file %s" % filename) 
 
 
     def readContentsFile(self):
     def readContentsFile(self):
         """ Reads the contents.xml file at the beginning of
         """ Reads the contents.xml file at the beginning of
@@ -3750,8 +3836,7 @@ class Packager:
                 xhost = he.makeXml(packager = self)
                 xhost = he.makeXml(packager = self)
                 xcontents.InsertEndChild(xhost)
                 xcontents.InsertEndChild(xhost)
 
 
-        contents = self.contents.items()
-        contents.sort()
+        contents = sorted(self.contents.items())
         for key, pe in contents:
         for key, pe in contents:
             xpackage = pe.makeXml()
             xpackage = pe.makeXml()
             xcontents.InsertEndChild(xpackage)
             xcontents.InsertEndChild(xpackage)

+ 2 - 0
direct/src/p3d/PatchMaker.py

@@ -1,3 +1,5 @@
+__all__ = ["PatchMaker"]
+
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.SeqValue import SeqValue
 from direct.p3d.SeqValue import SeqValue
 from panda3d.core import *
 from panda3d.core import *

+ 2 - 0
direct/src/p3d/ScanDirectoryNode.py

@@ -1,3 +1,5 @@
+__all__ = ["ScanDirectoryNode"]
+
 from panda3d.core import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument
 from panda3d.core import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument
 vfs = VirtualFileSystem.getGlobalPtr()
 vfs = VirtualFileSystem.getGlobalPtr()
 
 

+ 2 - 0
direct/src/p3d/SeqValue.py

@@ -1,3 +1,5 @@
+__all__ = ["SeqValue"]
+
 import types
 import types
 
 
 class SeqValue:
 class SeqValue:

+ 1 - 1
direct/src/p3d/coreapi.pdef

@@ -66,7 +66,7 @@ class images(package):
             token = '%s_img' % (name)
             token = '%s_img' % (name)
             configDict[token] = basename
             configDict[token] = basename
         else:
         else:
-            print "Could not locate %s" % (filename)
+            print("Could not locate %s" % (filename))
 
 
     # Also make a few special cases.  We use the same default image
     # Also make a few special cases.  We use the same default image
     # for many of the states.
     # for many of the states.

+ 20 - 9
direct/src/p3d/packp3d.py

@@ -57,6 +57,14 @@ Options:
      instead of -e for files that are uncompressible by their nature
      instead of -e for files that are uncompressible by their nature
      (e.g. mpg files).  This option may be repeated as necessary.
      (e.g. mpg files).  This option may be repeated as necessary.
 
 
+  -x ext
+     Marks files with the given extensions of needing to be physically
+     extracted to disk before they can be loaded.  This is used for
+     file types that cannot be loaded via the virtual file system,
+     such as .ico files on Windows.
+     This option is currently only implemented when deploying the
+     application with pdeploy.
+
   -p python_lib_dir
   -p python_lib_dir
      Adds a directory to search for additional Python modules.  You
      Adds a directory to search for additional Python modules.  You
      can use this to add your system's Python path, to allow packp3d
      can use this to add your system's Python path, to allow packp3d
@@ -103,7 +111,7 @@ class ArgumentError(StandardError):
     pass
     pass
 
 
 def makePackedApp(args):
 def makePackedApp(args):
-    opts, args = getopt.getopt(args, 'o:d:m:S:e:n:p:c:r:s:Dh')
+    opts, args = getopt.getopt(args, 'o:d:m:S:e:n:x:p:c:r:s:Dh')
 
 
     packager = Packager.Packager()
     packager = Packager.Packager()
 
 
@@ -134,6 +142,8 @@ def makePackedApp(args):
             packager.binaryExtensions.append(value)
             packager.binaryExtensions.append(value)
         elif option == '-n':
         elif option == '-n':
             packager.uncompressibleExtensions.append(value)
             packager.uncompressibleExtensions.append(value)
+        elif option == '-x':
+            packager.extractExtensions.append(value)
         elif option == '-p':
         elif option == '-p':
             sys.path.append(value)
             sys.path.append(value)
         elif option == '-c':
         elif option == '-c':
@@ -154,10 +164,10 @@ def makePackedApp(args):
                 PandaSystem.getPackageHostUrl(),
                 PandaSystem.getPackageHostUrl(),
                 os.path.split(sys.argv[0])[1],
                 os.path.split(sys.argv[0])[1],
                 '%s.%s' % (sys.version_info[0], sys.version_info[1]))
                 '%s.%s' % (sys.version_info[0], sys.version_info[1]))
-            sys.exit(1)
+            sys.exit(0)
 
 
     if not appFilename:
     if not appFilename:
-        raise ArgumentError, "No target app specified.  Use:\n%s -o app.p3d" % (os.path.split(sys.argv[0])[1])
+        raise ArgumentError, "No target app specified.  Use:\n  %s -o app.p3d\nUse -h to get more usage information." % (os.path.split(sys.argv[0])[1])
 
 
     if args:
     if args:
         raise ArgumentError, "Extra arguments on command line."
         raise ArgumentError, "Extra arguments on command line."
@@ -170,19 +180,20 @@ def makePackedApp(args):
       appDir = Filename('.')
       appDir = Filename('.')
     appBase = appFilename.getBasenameWoExtension()
     appBase = appFilename.getBasenameWoExtension()
 
 
-    if not main:
+    if main:
+        main = Filename.fromOsSpecific(main)
+        main.makeAbsolute(root)
+    else:
         main = Filename(root, 'main.py')
         main = Filename(root, 'main.py')
-        if main.exists():
-            main = 'main.py'
-        else:
+        if not main.exists():
             main = glob.glob(os.path.join(root.toOsSpecific(), '*.py'))
             main = glob.glob(os.path.join(root.toOsSpecific(), '*.py'))
             if len(main) == 0:
             if len(main) == 0:
                 raise ArgumentError, 'No Python files in root directory.'
                 raise ArgumentError, 'No Python files in root directory.'
             elif len(main) > 1:
             elif len(main) > 1:
                 raise ArgumentError, 'Multiple Python files in root directory; specify the main application with -m "main".'
                 raise ArgumentError, 'Multiple Python files in root directory; specify the main application with -m "main".'
-            main = os.path.split(main[0])[1]
 
 
-    main = Filename.fromOsSpecific(main)
+            main = Filename.fromOsSpecific(os.path.split(main[0])[1])
+            main.makeAbsolute(root)
 
 
     packager.installDir = appDir
     packager.installDir = appDir
     packager.allowPythonDev = allowPythonDev
     packager.allowPythonDev = allowPythonDev

+ 12 - 4
direct/src/p3d/panda3d.pdef

@@ -61,7 +61,7 @@ class panda3d(package):
            'panda3d.physics')
            'panda3d.physics')
 
 
     # Include various standard Python encodings.  The rest is in morepy.
     # Include various standard Python encodings.  The rest is in morepy.
-    module('encodings', 'encodings.aliases', 'encodings.undefined,'
+    module('encodings', 'encodings.aliases', 'encodings.undefined',
            'encodings.utf_8', 'encodings.ascii', 'encodings.string_escape',
            'encodings.utf_8', 'encodings.ascii', 'encodings.string_escape',
            'encodings.mbcs', 'encodings.latin_1', 'io')
            'encodings.mbcs', 'encodings.latin_1', 'io')
 
 
@@ -195,7 +195,7 @@ class morepy(package):
            'termios', 'tty', 'pty', 'fcntl', 'pipes', 'posixfile',
            'termios', 'tty', 'pty', 'fcntl', 'pipes', 'posixfile',
            'resource', 'nis', 'syslog', 'commands', 'ic', 'MacOS',
            'resource', 'nis', 'syslog', 'commands', 'ic', 'MacOS',
            'macostools', 'findertools', 'EasyDialogs', 'FrameWork',
            'macostools', 'findertools', 'EasyDialogs', 'FrameWork',
-           'autoGIL', 'ColorPicker')
+           'autoGIL', 'ColorPicker', 'ast')
 
 
     # To add the multitude of standard Python string encodings.
     # To add the multitude of standard Python string encodings.
     module('encodings', 'encodings.*')
     module('encodings', 'encodings.*')
@@ -362,8 +362,16 @@ class rocket(package):
     config(display_name = "Panda3D libRocket support")
     config(display_name = "Panda3D libRocket support")
     require('panda3d')
     require('panda3d')
 
 
-    module('panda3d.rocket', required = True)
-    module('_rocketcore', '_rocketcontrols')
+    file('rocket.py', extract = True, text = """
+from _rocketcore import *
+try:
+    from _rocketcontrols import *
+except ImportError:
+    pass
+""")
+
+    module('panda3d.rocket', '_rocketcore', required = True)
+    module('_rocketcontrols')
     file('libp3rocket.dll', required = True)
     file('libp3rocket.dll', required = True)
 
 
 class vrpn(package):
 class vrpn(package):

+ 17 - 8
direct/src/p3d/ppackage.py

@@ -123,6 +123,10 @@ Options:
      as such.  This only applies to .p3d packages, not to other types
      as such.  This only applies to .p3d packages, not to other types
      of packages!
      of packages!
 
 
+  -v
+     Emit a warning for any file not recognized by the dir() command
+     (indicating there may be a need for addExtensions(...)).
+     
   -h
   -h
      Display this help
      Display this help
 """
 """
@@ -135,12 +139,12 @@ from direct.p3d import Packager
 from panda3d.core import *
 from panda3d.core import *
 
 
 def usage(code, msg = ''):
 def usage(code, msg = ''):
-    print >> sys.stderr, usageText % {
+    sys.stderr.write(usageText % {
         'version' : PandaSystem.getPackageVersionString(),
         'version' : PandaSystem.getPackageVersionString(),
         'host' : PandaSystem.getPackageHostUrl(),
         'host' : PandaSystem.getPackageHostUrl(),
         'prog' : os.path.split(sys.argv[0])[1]
         'prog' : os.path.split(sys.argv[0])[1]
-        }
-    print >> sys.stderr, msg
+        })
+    sys.stderr.write(msg + '\n')
     sys.exit(code)
     sys.exit(code)
 
 
 installDir = None
 installDir = None
@@ -151,12 +155,13 @@ allowPythonDev = False
 universalBinaries = False
 universalBinaries = False
 systemRoot = None
 systemRoot = None
 ignoreSetHost = False
 ignoreSetHost = False
+verbosePrint = False
 p3dSuffix = ''
 p3dSuffix = ''
 platforms = []
 platforms = []
 
 
 try:
 try:
-    opts, args = getopt.getopt(sys.argv[1:], 'i:ps:S:DuP:R:Ha:h')
-except getopt.error, msg:
+    opts, args = getopt.getopt(sys.argv[1:], 'i:ps:S:DuP:R:Ha:hv')
+except getopt.error as msg:
     usage(1, msg)
     usage(1, msg)
 
 
 for opt, arg in opts:
 for opt, arg in opts:
@@ -188,10 +193,13 @@ for opt, arg in opts:
     elif opt == '-a':
     elif opt == '-a':
         p3dSuffix = arg
         p3dSuffix = arg
 
 
+    elif opt == '-v':
+        verbosePrint = True
+        
     elif opt == '-h':
     elif opt == '-h':
         usage(0)
         usage(0)
     else:
     else:
-        print 'illegal option: ' + arg
+        print('illegal option: ' + arg)
         sys.exit(1)
         sys.exit(1)
 
 
 if not args:
 if not args:
@@ -212,7 +220,7 @@ else:
 
 
 if universalBinaries:
 if universalBinaries:
     if platforms:
     if platforms:
-        print '\nYou may not specify both -u and -P.\n'
+        print('\nYou may not specify both -u and -P.\n')
         sys.exit(1)
         sys.exit(1)
     if PandaSystem.getPlatform().startswith('osx_'):
     if PandaSystem.getPlatform().startswith('osx_'):
         platforms = ['osx_i386', 'osx_amd64']
         platforms = ['osx_i386', 'osx_amd64']
@@ -230,6 +238,7 @@ for platform in platforms:
     packager.allowPythonDev = allowPythonDev
     packager.allowPythonDev = allowPythonDev
     packager.systemRoot = systemRoot
     packager.systemRoot = systemRoot
     packager.ignoreSetHost = ignoreSetHost
     packager.ignoreSetHost = ignoreSetHost
+    packager.verbosePrint = verbosePrint
     packager.p3dSuffix = p3dSuffix
     packager.p3dSuffix = p3dSuffix
 
 
     try:
     try:
@@ -242,7 +251,7 @@ for platform in platforms:
     except Packager.PackagerError:
     except Packager.PackagerError:
         # Just print the error message and exit gracefully.
         # Just print the error message and exit gracefully.
         inst = sys.exc_info()[1]
         inst = sys.exc_info()[1]
-        print inst.args[0]
+        print(inst.args[0])
         sys.exit(1)
         sys.exit(1)
 
 
 # An explicit call to exit() is required to exit the program, when
 # An explicit call to exit() is required to exit the program, when

+ 3 - 3
direct/src/p3d/thirdparty.pdef

@@ -137,7 +137,7 @@ class pyopengl(package):
     module('OpenGL.GLU', 'OpenGL.GLUT', 'OpenGL.GLE', 'OpenGL.GLX')
     module('OpenGL.GLU', 'OpenGL.GLUT', 'OpenGL.GLE', 'OpenGL.GLX')
 
 
 class httplib2(package):
 class httplib2(package):
-    config(display_name = "httplib2")
+    config(display_name = "httplib2", platform_specific = False)
     require('panda3d')
     require('panda3d')
 
 
     module('httplib2', required = True)
     module('httplib2', required = True)
@@ -149,7 +149,7 @@ class box2d(package):
     module('Box2D', required = True)
     module('Box2D', required = True)
 
 
 class pyglet(package):
 class pyglet(package):
-    config(display_name = "pyglet")
-    require('panda3d')
+    config(display_name = "pyglet", platform_specific = False)
+    require('panda3d', 'morepy')
 
 
     module('pyglet', required = True)
     module('pyglet', required = True)

Vissa filer visades inte eftersom för många filer har ändrats