ソースを参照

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

David Rose 10 年 前
コミット
439ee70845
100 ファイル変更619 行追加1276 行削除
  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
 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
-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:
   irc:
     channels:

+ 6 - 1
contrib/.gitignore

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

+ 1 - 0
direct/.gitignore

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

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

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

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

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

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

@@ -1,6 +1,5 @@
 
 from ClusterClient import *
-import string
 
 # A dictionary of information for various cluster configurations.
 # 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
 # both ClusterClient and ClusterServer.
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.distributed.PyDatagram import PyDatagram
 from direct.distributed.PyDatagramIterator import PyDatagramIterator
 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 direct.distributed.MsgTypes import *
 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
         # that is outside of the world to step up to the floor when they
         # 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.addSolid(cRay)
+        cRayNode.addSolid(self.cRay)
         self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
         cRayNode.setFromCollideMask(bitmask)
         cRayNode.setIntoCollideMask(BitMask32.allOff())
@@ -697,8 +697,4 @@ class GravityWalker(DirectObject.DirectObject):
     # There are sometimes issues if the collision ray height is
     # so tall that it collides with multiple levels of floors.
     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
 
-#undef HAVE_LONG_LONG  // NSPR and Python both define this.
+#define PY_SSIZE_T_CLEAN 1
+
 #undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
 #include <Python.h>
 
 // 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 import ShowBase
-ShowBase.ShowBase()
+base = ShowBase.ShowBase()
 
 # Put an axis in the world:
 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);
     argv[i] = new wchar_t[len + 1];
     mbstowcs(argv[i], mb_argv[i], len);
-    argv[i][len] = NULL;
+    argv[i][len] = 0;
   }
   // Just for good measure
   argv[argc] = NULL;

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

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

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

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

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

@@ -6,7 +6,6 @@ from LoggerGlobal import defaultLogger
 from direct.showbase import PythonUtil
 from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
 import time
-import types
 import sys
 
 class Notifier:
@@ -236,7 +235,7 @@ class Notifier:
         Prints the string to output followed by a newline.
         """
         if self.streamWriter:
-            self.streamWriter.appendData(string + '\n')
+            self.streamWriter.write(string + '\n')
         else:
             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
 as an INPUT_FILTER in doxygen. """
 
-import sys, re, os
+import sys, os
 
 # Explicitly include these files.  Besides these, all
 # 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__ = []
 
-import os, re
+import os
 import panda3d, pandac
 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())
             self.computeCOA(base.direct.iRay.pickGeom(skipFlags = skipFlags))
             # Record reference point
-            self.coaMarkerRef.iPosHprScale(base.cam)
+            self.coaMarkerRef.setPosHprScale(base.cam, 0, 0, 0, 0, 0, 0, 1, 1, 1)
             # Record entries
             self.cqEntries = []
             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 DirectUtil import *
 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',
               '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 DirectUtil 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
 
 class DirectLight(NodePath):

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

@@ -2,7 +2,7 @@ import math
 import types
 import string
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from DirectUtil import *
 
 from direct.showbase.DirectObject import DirectObject
@@ -304,6 +304,7 @@ class DirectSession(DirectObject):
         except NameError:
             # Has the clusterMode been set via a config variable?
             self.clusterMode = base.config.GetString("cluster-mode", '')
+
         if self.clusterMode == 'client':
             self.cluster = createClusterClient()
         elif self.clusterMode == 'server':
@@ -400,7 +401,7 @@ class DirectSession(DirectObject):
 
         if self.oobeMode:
             # 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(
                 2.0, pos = Point3(0), hpr = Vec3(0), 
                 other = base.direct.cameraControl.camManipRef,
@@ -416,7 +417,7 @@ class DirectSession(DirectObject):
             cameraParent = self.camera.getParent()
             # Prepare oobe camera
             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
             self.cam.reparentTo(self.oobeCamera)
             # Position a target point to lerp the oobe camera to
@@ -432,13 +433,13 @@ class DirectSession(DirectObject):
 
     def beginOOBE(self):
         # 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
         self.oobeMode = 1
 
     def endOOBE(self):
         # 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.
         self.cam.reparentTo(self.trueCamera)
         base.direct.camera = self.trueCamera
@@ -806,7 +807,7 @@ class DirectSession(DirectObject):
                            [nodePath, oldParent, self.activeParent, fWrt])
 
     def isNotCycle(self, nodePath, parent):
-        if nodePath.id() == parent.id():
+        if nodePath == parent:
             print 'DIRECT.reparent: Invalid parent'
             return 0
         elif parent.hasParent():
@@ -1308,6 +1309,3 @@ class DisplayRegionList(DirectObject):
             if drc.cam == cam:
                 self.displayRegionList.remove(drc)
                 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.GridParent import GridParent
-from pandac.PandaModules import EmbeddedValue
 
 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
 # 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
 
 #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
 # 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
 
 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
-notify = directNotify.newCategory("Interval")
-Dtool_ObjectToDict(CInterval,"notify", notify)
-del notify
+
+CInterval.DtoolClassDict["notify"] = directNotify.newCategory("Interval")
+
 #####################################################################
 def setT(self, t):
     # Overridden from the C++ function to call privPostEvent
@@ -10,7 +11,7 @@ def setT(self, t):
     self.setT_Old(t)
     self.privPostEvent()
 
-Dtool_ObjectToDict(CInterval, "setT_Old", CInterval.setT)
+CInterval.DtoolClassDict["setT_Old"] = CInterval.setT
 Dtool_funcToMethod(setT, CInterval)
 del setT
 #####################################################################

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

@@ -10,22 +10,16 @@ of the NodePath class
 
 ####################################################################
 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()
 
 Dtool_funcToMethod(id, NodePath)
 del id
 #####################################################################
-
-##    def __hash__(self):  // inside c code
-##        return self.getKey()
-#####################################################################
-
-    # For iterating over children
 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())
 
 Dtool_funcToMethod(getChildrenAsList, NodePath)
@@ -35,7 +29,7 @@ del getChildrenAsList
 def printChildren(self):
         """Prints out the children of the bottom node of a node path"""
         for child in self.getChildren():
-            print child.getName()
+            print(child.getName())
 Dtool_funcToMethod(printChildren, NodePath)
 del printChildren
 #####################################################################
@@ -95,8 +89,8 @@ del isolate
 #####################################################################
 
 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
         # before node is deleted
         messenger.send('preRemoveNodePath', [self])
@@ -109,11 +103,11 @@ del remove
 def lsNames(self):
         """Walk down a tree and print out the path"""
         if self.isEmpty():
-            print "(empty)"
+            print("(empty)")
         else:
             type = self.node().getType().getName()
             name = self.getName()
-            print type + "  " + name
+            print(type + "  " + name)
             self.lsNamesRecurse()
 
 Dtool_funcToMethod(lsNames, NodePath)
@@ -124,7 +118,7 @@ def lsNamesRecurse(self, indentString=' '):
         for nodePath in self.getChildren():
             type = nodePath.node().getType().getName()
             name = nodePath.getName()
-            print indentString + type + "  " + name
+            print(indentString + type + "  " + name)
             nodePath.lsNamesRecurse(indentString + " ")
 
 Dtool_funcToMethod(lsNamesRecurse, NodePath)
@@ -138,7 +132,7 @@ def reverseLsNames(self):
         for nodePath in ancestry:
             type = nodePath.node().getType().getName()
             name = nodePath.getName()
-            print indentString + type + "  " + name
+            print(indentString + type + "  " + name)
             indentString = indentString + " "
 
 Dtool_funcToMethod(reverseLsNames, NodePath)
@@ -146,7 +140,7 @@ del reverseLsNames
 #####################################################################
 def getAncestry(self):
         """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.reverse()
         return ancestors
@@ -197,11 +191,11 @@ def printPos(self, other = None, sd = 2):
         else:
             pos = self.getPos()
             otherString = ''
-        print (self.getName() + '.setPos(' + otherString +
+        print((self.getName() + '.setPos(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] +
-               ')\n')
+               ')\n'))
 Dtool_funcToMethod(printPos, NodePath)
 del printPos
 #####################################################################
@@ -215,11 +209,11 @@ def printHpr(self, other = None, sd = 2):
         else:
             hpr = self.getHpr()
             otherString = ''
-        print (self.getName() + '.setHpr(' + otherString +
+        print((self.getName() + '.setHpr(' + otherString +
                formatString % hpr[0] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[2] +
-               ')\n')
+               ')\n'))
 Dtool_funcToMethod(printHpr, NodePath)
 del printHpr
 #####################################################################
@@ -233,11 +227,11 @@ def printScale(self, other = None, sd = 2):
         else:
             scale = self.getScale()
             otherString = ''
-        print (self.getName() + '.setScale(' + otherString +
+        print((self.getName() + '.setScale(' + otherString +
                formatString % scale[0] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[2] +
-               ')\n')
+               ')\n'))
 
 Dtool_funcToMethod(printScale, NodePath)
 del printScale
@@ -253,14 +247,14 @@ def printPosHpr(self, other = None, sd = 2):
             pos = self.getPos()
             hpr = self.getHpr()
             otherString = ''
-        print (self.getName() + '.setPosHpr(' + otherString +
+        print((self.getName() + '.setPosHpr(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] + ', ' +
                formatString % hpr[0] + ', ' +
                formatString % hpr[1] + ', ' +
                formatString % hpr[2] +
-               ')\n')
+               ')\n'))
 
 Dtool_funcToMethod(printPosHpr, NodePath)
 del printPosHpr
@@ -278,7 +272,7 @@ def printPosHprScale(self, other = None, sd = 2):
             hpr = self.getHpr()
             scale = self.getScale()
             otherString = ''
-        print (self.getName() + '.setPosHprScale(' + otherString +
+        print((self.getName() + '.setPosHprScale(' + otherString +
                formatString % pos[0] + ', ' +
                formatString % pos[1] + ', ' +
                formatString % pos[2] + ', ' +
@@ -288,14 +282,14 @@ def printPosHprScale(self, other = None, sd = 2):
                formatString % scale[0] + ', ' +
                formatString % scale[1] + ', ' +
                formatString % scale[2] +
-               ')\n')
+               ')\n'))
 
 Dtool_funcToMethod(printPosHprScale, NodePath)
 del printPosHprScale
 #####################################################################
 
 def printTransform(self, other = None, sd = 2, fRecursive = 0):
-    from pandac.PandaModules import Vec3
+    from panda3d.core import Vec3
     fmtStr = '%%0.%df' % sd
     name = self.getName()
     if other == None:
@@ -306,23 +300,23 @@ def printTransform(self, other = None, sd = 2, fRecursive = 0):
         pos = transform.getPos()
         if not pos.almostEqual(Vec3(0)):
             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():
         hpr = transform.getHpr()
         if not hpr.almostEqual(Vec3(0)):
             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.hasUniformScale():
             scale = transform.getUniformScale()
             if scale != 1.0:
                 outputString = '%s.setScale(%s)' % (name, fmtStr)
-                print outputString % scale
+                print(outputString % scale)
         else:
             scale = transform.getScale()
             if not scale.almostEqual(Vec3(1)):
                 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:
         for child in self.getChildren():
             child.printTransform(other, sd, fRecursive)
@@ -383,700 +377,6 @@ def iPosHprScale(self, other = None):
 Dtool_funcToMethod(iPosHprScale, NodePath)
 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):
         base.startDirect(fWantTk = 1)
         from direct.tkpanels import Placer
@@ -1253,8 +553,8 @@ Dtool_funcToMethod(colorScaleInterval, NodePath)
 del colorScaleInterval
 #####################################################################
 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)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
@@ -1267,8 +567,8 @@ Dtool_funcToMethod(attachCollisionSphere, NodePath)
 del attachCollisionSphere
 #####################################################################
 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)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
@@ -1281,8 +581,8 @@ Dtool_funcToMethod(attachCollisionSegment, NodePath)
 del attachCollisionSegment
 #####################################################################
 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)
         collNode = CollisionNode(name)
         collNode.addSolid(coll)
@@ -1296,7 +596,7 @@ del attachCollisionRay
 #####################################################################
 def flattenMultitex(self, stateFrom = None, target = None,
                         useGeom = 0, allowTexMat = 0, win = None):
-        from pandac.PandaModules import MultitexReducer
+        from panda3d.core import MultitexReducer
         mr = MultitexReducer()
         if target != None:
             mr.setTarget(target)
@@ -1466,26 +766,31 @@ del r_constructCollisionTree
 
 #####################################################################
 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.addNode(self.node())
         if sga.getNumLodNodes() == 0:
-                print sga
+                print(sga)
         else:
-                print "At highest LOD:"
+                print("At highest LOD:")
                 sga2 = SceneGraphAnalyzer()
                 sga2.setLodMode(sga2.LMHighest)
                 sga2.addNode(self.node())
-                print sga2
+                print(sga2)
 
-                print "\nAt lowest LOD:"
+                print("\nAt lowest LOD:")
                 sga2.clear()
                 sga2.setLodMode(sga2.LMLowest)
                 sga2.addNode(self.node())
-                print sga2
+                print(sga2)
 
-                print "\nAll nodes:"
-                print sga
+                print("\nAll nodes:")
+                print(sga)
 
 Dtool_funcToMethod(analyze, NodePath)
 del analyze

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

@@ -14,7 +14,7 @@ def asTuple(self):
     """
     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)
 Dtool_funcToMethod(asTuple, VBase3)
 del asTuple

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

@@ -14,7 +14,7 @@ def asTuple(self):
     """
     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)
 
 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 sys
 import os
-import glob
-import types
 import time
 from direct.ffi import FFIConstants
 
@@ -224,7 +222,7 @@ def doErrorCheck():
         FFIConstants.CodeModuleNameList = codeLibs
 
 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
     # previous runs before we begin.
@@ -337,7 +335,7 @@ def run():
 
     if doHTML:
         from direct.directscripts import gendocs
-        from pandac.PandaModules import PandaSystem
+        from panda3d.core import PandaSystem
         versionString = '%s %s' % (
             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 string
 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 FFIConstants
 DoGenPyCode.outputCodeDir = PANDAC
 DoGenPyCode.outputHTMLDir = os.path.join(PANDAC,"..","doc")
 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 Filename
 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="""
 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 TextureStage
 from panda3d.core import GraphicsPipe, GraphicsOutput
 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 AuxBitplaneAttrib
 from direct.directnotify.DirectNotifyGlobal import *

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

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

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

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

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

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

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

@@ -5,7 +5,7 @@ __all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse',
            'EventArgument', ]
 
 from direct.showbase.DirectObject import DirectObject
-import types
+
 
 class PushesStateChanges:
     # 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']
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 from DirectFrame import *
 

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -3,7 +3,8 @@
 __all__ = ['DirectGuiBase', 'DirectGuiWidget']
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import get_config_showbase
 import DirectGuiGlobals as DGG
 from OnscreenText import *
 from OnscreenGeom import *
@@ -11,9 +12,7 @@ from OnscreenImage import *
 from direct.directtools.DirectUtil import ROUND_TO
 from direct.showbase import DirectObject
 from direct.task import Task
-from direct.showbase import ShowBase
 from direct.showbase.PythonUtil import recordCreationStackStr
-from pandac.PandaModules import PStatCollector
 import types
 
 guiObjectCollector = PStatCollector("Client::GuiObjects")
@@ -632,7 +631,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         """
         # Need to tack on gui item specific id
         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
             print gEvent
             print StackTrace()
@@ -655,7 +654,7 @@ def setGuiGridSpacing(spacing):
 # 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
 # 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
     # call obj.printCreationStackTrace() to figure out what code created it
     DirectGuiBase = recordCreationStackStr(DirectGuiBase)
@@ -668,8 +667,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     # Determine the default initial state for inactive (or
     # unclickable) components.  If we are in edit mode, these are
     # 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:
         inactiveInitState = DGG.NORMAL
     else:
@@ -1069,8 +1067,8 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     def printConfig(self, indent = 0):
         space = ' ' * indent
         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
         for child in self.getChildren():
             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
 that can be used during widget construction
 """
-from pandac.PandaModules import *
+from panda3d.core import *
 
 defaultFont = None
 defaultFontFunc = TextNode.getDefaultFont

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -2,10 +2,10 @@
 
 __all__ = ['OnscreenText', 'Plain', 'ScreenTitle', 'ScreenPrompt', 'NameConfirm', 'BlackOnWhite']
 
-from pandac.PandaModules import *
+from panda3d.core import *
 import DirectGuiGlobals as DGG
 from direct.showbase.DirectObject import DirectObject
-import string,types
+import types
 
 ## 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

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

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

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

@@ -2,7 +2,8 @@
 
 __all__ = ['AnimControlInterval']
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 import Interval
 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']
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.showbase.MessengerGlobal import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 import Interval
-import types
 
 
 #############################################################

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

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

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

@@ -4,10 +4,9 @@ __all__ = ['Interval']
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
-from pandac.PandaModules import *
 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
 
 class Interval(DirectObject):

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

@@ -10,15 +10,17 @@ from FunctionInterval import *
 from LerpInterval import *
 from IndirectInterval 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 ProjectileInterval import *
 from MetaInterval 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']
 
-from pandac.PandaModules import *
-from pandac import PandaModules
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import *
 from direct.showbase import EventManager
-import Interval
-import types
 import fnmatch
 
 class IntervalManager(CIntervalManager):

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

@@ -4,13 +4,15 @@ __all__ = []
 
 
 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 direct.actor.Actor import *
 
     from direct.directutil import Mopath
 
+    base = ShowBase()
+
     boat = loader.loadModel('models/misc/smiley')
     boat.reparentTo(render)
 
@@ -205,4 +207,4 @@ if __name__ == "__main__":
         # return mt
 
     test(5)
-    run()
+    base.run()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -6,11 +6,11 @@ __all__ = ['TestInterval']
 Contains the ParticleInterval class
 """
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from Interval import Interval
 
-from direct.particles import ParticleEffect
 
 class TestInterval(Interval):
     # 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.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 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 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 import core
 from direct.stdpy import file, glob
@@ -43,7 +31,7 @@ from direct.p3d.InstalledHostData import InstalledHostData
 from direct.p3d.InstalledPackageData import InstalledPackageData
 
 # 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):
     pass
@@ -471,7 +459,7 @@ class AppRunner(DirectObject):
             file.unlink()
             return False
 
-        if not fileSpec.fullVerify(pathname = localPathname):
+        if not fileSpec.fullVerify(pathname = localPathname, notify = self.notify):
             # No good after download.
             self.notify.info("%s is still no good after downloading." % (url))
             return False
@@ -569,14 +557,14 @@ class AppRunner(DirectObject):
             for packageData in hostData.packages:
                 totalSize += packageData.totalSize
         self.notify.info("Total Panda3D disk space used: %s MB" % (
-            (totalSize + 524288) / 1048576))
+            (totalSize + 524288) // 1048576))
 
         if self.verifyContents == self.P3DVCNever:
             # We're not allowed to delete anything anyway.
             return
 
         self.notify.info("Configured max usage is: %s MB" % (
-            (self.maxDiskUsage + 524288) / 1048576))
+            (self.maxDiskUsage + 524288) // 1048576))
         if totalSize <= self.maxDiskUsage:
             # Still within budget; no need to clean up anything.
             return
@@ -634,13 +622,13 @@ class AppRunner(DirectObject):
         try:
             taskMgr.run()
 
-        except SystemExit:
+        except SystemExit as err:
             # Presumably the window has already been shut down here, but shut
             # it down again for good measure.
-            if hasattr(__builtin__, "base"):
+            if hasattr(builtins, "base"):
                 base.destroy()
 
-            self.notify.info("Normal exit.")
+            self.notify.info("Normal exit with status %s." % repr(err.code))
             raise
 
         except:
@@ -696,9 +684,10 @@ class AppRunner(DirectObject):
             # Replace the builtin open and file symbols so user code will get
             # our versions by default, which can open and read files out of
             # 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.walk = file.walk
             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.gui.DirectWaitBar import DirectWaitBar
 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"]
 
-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.showbase.AppRunnerGlobal import appRunner
 from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
@@ -21,8 +21,8 @@ try:
 except ImportError:
     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
 # an archive that should be owned by root.
@@ -73,7 +73,7 @@ class Standalone:
 
         self.tempDir = Filename.temporary("", self.basename, "") + "/"
         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()
         if not self.host.hasContentsFile:
@@ -99,6 +99,9 @@ class Standalone:
         if len(platforms) == 0:
             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.makeDir()
         for platform in platforms:
@@ -158,10 +161,10 @@ class Standalone:
 
         # Find the magic size string and replace it with the real size,
         # 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
         Standalone.notify.info("Creating %s..." % output)
@@ -170,12 +173,15 @@ class Standalone:
         ohandle.write(p3dembed_data)
 
         # 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(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.
         phandle = open(self.p3dfile.toOsSpecific(), "rb")
@@ -233,7 +239,7 @@ class PackageTree:
         if hostUrl in self.hosts:
             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.readContentsFile():
                 if not host.downloadContentsFile(self.http):
@@ -391,7 +397,7 @@ class Icon:
         vfs = VirtualFileSystem.getGlobalPtr()
         stream = vfs.openWriteFile(fn, False, True)
         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'}
         mask_types = {16: 's8mk', 32: 'l8mk', 48: 'h8mk', 128: 't8mk'}
@@ -404,7 +410,7 @@ class Icon:
                 if pngtype is None:
                     continue
                 icns.write(png_types[size])
-                icns.write('\0\0\0\0')
+                icns.write(b'\0\0\0\0')
                 start = icns.tell()
 
                 image.write(stream, "", pngtype)
@@ -444,6 +450,7 @@ class Installer:
     notify = directNotify.newCategory("Installer")
 
     def __init__(self, p3dfile, shortname, fullname, version, tokens = {}):
+        self.p3dFilename = p3dfile
         if not shortname:
             shortname = p3dfile.getBasenameWoExtension()
         self.shortname = shortname
@@ -477,22 +484,16 @@ class Installer:
         if not self.authoremail and ' ' not in uname:
             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
         mf = Multifile()
-        if not mf.openRead(p3dfile):
+        if not mf.openRead(self.p3dFilename):
             Installer.notify.error("Not a Panda3D application: %s" % (p3dfile))
             return
 
         # 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.extracts = []
         i = mf.findSubfile('p3d_info.xml')
         if i >= 0:
             stream = mf.openReadSubfile(i)
@@ -511,14 +512,54 @@ class Installer:
                         p3dRequires.Attribute('host')))
                     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:
                     p3dConfig = p3dPackage.FirstChildElement('config')
                     if p3dConfig:
                         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:
             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):
         try:
             appRunner.rmtree(self.tempDir)
@@ -533,6 +574,22 @@ class Installer:
         if not self.includeRequires:
             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.installPackage("images", None, self.standalone.host.hostUrl)
 
@@ -618,6 +675,9 @@ class Installer:
         if len(platforms) == 0:
             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.makeDir()
         for platform in platforms:
@@ -660,7 +720,8 @@ class Installer:
 
         Filename(tempdir, "usr/bin/").makeDir()
         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:
             extraTokens = {}
         self.standalone.build(Filename(tempdir, "usr/bin/" + self.shortname.lower()), platform, extraTokens)
@@ -712,7 +773,7 @@ class Installer:
         print >>desktop, "Type=Application"
         desktop.close()
 
-        if self.includeRequires:
+        if self.includeRequires or self.extracts:
             hostDir = Filename(tempdir, "usr/lib/%s/" % self.shortname.lower())
             hostDir.makeDir()
             self.installPackagesInto(hostDir, platform)
@@ -742,16 +803,18 @@ class Installer:
         tempdir, totsize = self.__buildTempLinux(platform)
 
         # 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.mtime = modtime
         controlinfo.size = controlfile.tell()
@@ -762,33 +825,43 @@ class Installer:
         if output.exists():
             output.unlink()
         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()
         ctarfile = tarfile.open("control.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         ctarfile.addfile(controlinfo, controlfile)
         ctarfile.close()
         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()
         dtarfile = tarfile.open("data.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
         dtarfile.add(Filename(tempdir, "usr").toOsSpecific(), "/usr")
         dtarfile.close()
         dtarsize = debfile.tell() - dtaroffs
-        if (dtarsize & 1): debfile.write("\x0A")
+        if (dtarsize & 1): debfile.write(b"\x0A")
 
         # Write the correct sizes of the archives.
         debfile.seek(ctaroffs - 12)
-        debfile.write("%-10ld" % ctarsize)
+        debfile.write(str(ctarsize).encode().ljust(10, b' '))
         debfile.seek(dtaroffs - 12)
-        debfile.write("%-10ld" % dtarsize)
+        debfile.write(str(dtarsize).encode().ljust(10, b' '))
 
         debfile.close()
 
@@ -815,18 +888,20 @@ class Installer:
         tempdir, totsize = self.__buildTempLinux(platform)
 
         # 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 != "":
-            print >>pkginfo, "license = %s" % self.licensename
+            pout.write(u"license = %s\n" % self.licensename)
+        pout.flush()
         pkginfoinfo = TarInfoRoot(".PKGINFO")
         pkginfoinfo.mtime = modtime
         pkginfoinfo.size = pkginfo.tell()
@@ -853,7 +928,7 @@ class Installer:
         exefile = Filename(output, "Contents/MacOS/" + self.shortname)
         exefile.makeDir()
         if self.includeRequires:
-            extraTokens = {"host_dir" : "../Resources"}
+            extraTokens = {"host_dir": "../Resources", "start_dir": "../Resources"}
         else:
             extraTokens = {}
         self.standalone.build(exefile, platform, extraTokens)
@@ -1064,7 +1139,7 @@ class Installer:
         exefile = Filename(Filename.getTempDirectory(), self.shortname + ".exe")
         exefile.unlink()
         if self.includeRequires:
-            extraTokens = {"host_dir" : "."}
+            extraTokens = {"host_dir": ".", "start_dir": "."}
         else:
             extraTokens = {}
         self.standalone.build(exefile, platform, extraTokens)

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

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

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

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

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

@@ -1,3 +1,5 @@
+__all__ = ["InstalledPackageData"]
+
 class InstalledPackageData:
     """ A list of instances of this class is maintained 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
 code that runs in a browser via the web plugin. """
 
+__all__ = ["UndefinedObject", "Undefined", "ConcreteStruct", "BrowserObject", "MethodWrapper"]
+
 import types
 
 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
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.ScanDirectoryNode import ScanDirectoryNode
@@ -275,7 +277,7 @@ class PackageInfo:
             # We've already got one.
             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.
             self.http = http
 
@@ -521,7 +523,8 @@ class PackageInfo:
 
         # In case of unexpected failures on the internet, we will retry
         # 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[:])
 
         pc.stop()
@@ -1149,7 +1152,7 @@ class PackageInfo:
         thisDir = ScanDirectoryNode(self.getPackageDir(), ignoreUsageXml = True)
         diskSpace = thisDir.getTotalSize()
         self.notify.info("Package %s uses %s MB" % (
-            self.packageName, (diskSpace + 524288) / 1048576))
+            self.packageName, (diskSpace + 524288) // 1048576))
         return diskSpace
 
     def markUsed(self):

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

@@ -1,3 +1,5 @@
+__all__ = ["PackageInstaller"]
+
 from direct.showbase.DirectObject import DirectObject
 from direct.stdpy.threading import Lock, RLock
 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.SeqValue import SeqValue
 from direct.directnotify.DirectNotifyGlobal import *
 from panda3d.core import *
-import copy
 import shutil
 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
 application. """
 
+__all__ = ["Packager", "PackagerError", "OutsideOfPackageError", "ArgumentError"]
+
 # Important to import panda3d first, to avoid naming conflicts with
 # Python's "string" and "Loader" names that are imported later.
 from panda3d.core import *
 import sys
 import os
 import glob
-import marshal
 import string
 import types
 import getpass
-import platform
 import struct
 import subprocess
+import copy
 from direct.p3d.FileSpec import FileSpec
 from direct.p3d.SeqValue import SeqValue
 from direct.showbase import Loader
@@ -185,7 +186,7 @@ class Packager:
         def getKey(self):
             """ Returns a tuple used for sorting the PackageEntry
             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,
                      installDir, descFilename, importDescFilename):
@@ -299,8 +300,7 @@ class Packager:
                 xhost.InsertEndChild(xmirror)
 
             if packager:
-                altHosts = self.altHosts.items()
-                altHosts.sort()
+                altHosts = sorted(self.altHosts.items())
                 for keyword, alt in altHosts:
                     he = packager.hosts.get(alt, None)
                     if he:
@@ -372,9 +372,15 @@ class Packager:
             self.requiredFilenames = []
             self.requiredModules = []
 
+            # A list of required packages that were missing.
+            self.missingPackages = []
+
             # This records the current list of modules we have added so
             # far.
             self.freezer = FreezeTool.Freezer(platform = self.packager.platform)
+            
+            # Map of extensions to files to number (ignored by dir)
+            self.ignoredDirFiles = {}
 
         def close(self):
             """ 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'
                 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:
                 self.host = self.packager.host
 
@@ -454,7 +466,7 @@ class Packager:
             if self.p3dApplication:
                 allowPythonDev = self.configs.get('allow_python_dev', 0)
                 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
 
@@ -485,6 +497,12 @@ class Packager:
             as a true package.  Either is implemented with a
             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()
 
             # Write the multifile to a temporary filename until we
@@ -570,8 +588,7 @@ class Packager:
 
             # Add known module names.
             self.moduleNames = {}
-            modules = self.freezer.modules.items()
-            modules.sort()
+            modules = sorted(self.freezer.modules.items())
             for newName, mdef in modules:
                 if mdef.guess:
                     # Not really a module.
@@ -702,7 +719,7 @@ class Packager:
             self.packageDesc = packageDir + self.packageDesc
             self.packageImportDesc = packageDir + self.packageImportDesc
 
-            print "Generating %s" % (self.packageFilename)
+            print("Generating %s" % (self.packageFilename))
 
             if self.p3dApplication:
                 self.packageFullpath = Filename(self.packager.p3dInstallDir, self.packageFilename)
@@ -820,6 +837,14 @@ class Packager:
             self.packager.contents[pe.getKey()] = pe
             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()
             return True
 
@@ -1232,13 +1257,13 @@ class Packager:
                 elf.close()
                 return None
 
-            if not ident.startswith("\177ELF"):
+            if not ident.startswith(b"\177ELF"):
                 # No elf magic!  Beware of orcs.
                 return None
 
             # 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]
             sectionStruct = byteOrder + ("4xI8xIII8xI", "4xI16xQQI12xQ")[elfClass]
             dynamicStruct = byteOrder + ("iI", "qQ")[elfClass]
@@ -1272,17 +1297,17 @@ class Packager:
                 elf.seek(offset)
                 data = elf.read(entsize)
                 tag, val = struct.unpack_from(dynamicStruct, data)
-                newSectionData = ""
+                newSectionData = b""
                 startReplace = None
                 pad = 0
 
                 # Read tags until we find a NULL tag.
                 while tag != 0:
                     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:
-                        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.
                         if not startReplace:
                             startReplace = elf.tell() - entsize
@@ -1296,7 +1321,7 @@ class Packager:
                     tag, val = struct.unpack_from(dynamicStruct, data)
 
                 if startReplace is not None:
-                    newSectionData += data + ("\0" * pad)
+                    newSectionData += data + (b"\0" * pad)
                     rewriteSections.append((startReplace, newSectionData))
             elf.close()
 
@@ -1329,7 +1354,7 @@ class Packager:
             for offset, data in rewriteSections:
                 elf.seek(offset)
                 elf.write(data)
-            elf.write("\0" * pad)
+            elf.write(b"\0" * pad)
             elf.close()
             return filenames
 
@@ -1468,6 +1493,10 @@ class Packager:
                     xhost = he.makeXml(packager = self.packager)
                     xpackage.InsertEndChild(xhost)
 
+            self.extracts.sort()
+            for name, xextract in self.extracts:
+                xpackage.InsertEndChild(xextract)
+
             doc.InsertEndChild(xpackage)
 
             # Write the xml file to a temporary file on disk, so we
@@ -1813,7 +1842,10 @@ class Packager:
                         self.notify.warning(message)
                     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):
             # Precompile egg files to bam's.
@@ -2161,8 +2193,10 @@ class Packager:
                     ext = Filename(lowerName).getExtension()
                     if ext not in self.packager.nonuniqueExtensions:
                         self.skipFilenames[lowerName] = True
+
                 for moduleName, mdef in package.moduleNames.items():
-                    self.skipModules[moduleName] = mdef
+                    if not mdef.exclude:
+                        self.skipModules[moduleName] = mdef
 
     # Packager constructor
     def __init__(self, platform = None):
@@ -2185,6 +2219,9 @@ class Packager:
         # ignoring any request to specify a particular download host,
         # e.g. for testing and development.
         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,
         # before the .p3d extension.
@@ -2333,7 +2370,7 @@ class Packager:
 
         # Binary files that are copied (and compressed) without
         # processing.
-        self.binaryExtensions = [ 'ttf', 'TTF', 'mid', 'ico' ]
+        self.binaryExtensions = [ 'ttf', 'TTF', 'mid', 'ico', 'cur' ]
 
         # Files that can have an existence in multiple different
         # packages simultaneously without conflict.
@@ -2373,7 +2410,7 @@ class Packager:
                 }
 
         # 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.
         self.platformSpecificExtensions = self.executableExtensions[:]
@@ -2390,6 +2427,14 @@ class Packager:
         # should be added exactly byte-for-byte as they are.
         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
         # case-insensitive filesystems (like Windows and OSX), put the
         # lowercase filename here.  Case-sensitive filesystems should
@@ -2456,7 +2501,7 @@ class Packager:
         if not os.path.isfile('/sbin/ldconfig'):
             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()
 
         if handle.returncode != 0:
@@ -2617,12 +2662,20 @@ class Packager:
             if dirname.makeTrueCase():
                 searchPath.appendDirectory(dirname)
 
+    def _ensureExtensions(self):
+        self.knownExtensions = \
+            self.imageExtensions + \
+            self.modelExtensions + \
+            self.textExtensions + \
+            self.binaryExtensions + \
+            self.uncompressibleExtensions + \
+            self.unprocessedExtensions
 
     def setup(self):
         """ Call this method to initialize the class after filling in
         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
 
@@ -2710,11 +2763,15 @@ class Packager:
         # errors, and that the pdef file doesn't contain any really
         # crazy Python code, all this will do is fill in the
         # '__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
         # dictionary causes problems with resolving symbols within a
         # class scope.  So, we just use one dictionary, the globals.
-        execfile(packageDef.toOsSpecific(), globals)
+        exec(code, globals)
 
         packages = []
 
@@ -2979,10 +3036,10 @@ class Packager:
             # environment.
             return None
 
+        # Make sure we have a fresh version of the contents file.
         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 = []
         packageInfo = host.getPackage(packageName, version, platform = platform)
@@ -3031,7 +3088,7 @@ class Packager:
         tuples = []
         for package in packages:
             version = self.__makeVersionTuple(package.version)
-            tuples.append((version, file))
+            tuples.append((version, package))
         tuples.sort(reverse = True)
 
         return [t[1] for t in tuples]
@@ -3044,7 +3101,7 @@ class Packager:
         tuples = []
         for package in packages:
             version = self.__makeVersionTuple(package.packageVersion)
-            tuples.append((version, file))
+            tuples.append((version, package))
         tuples.sort(reverse = True)
 
         return [t[1] for t in tuples]
@@ -3103,9 +3160,9 @@ class Packager:
         if panda1.version == panda2.version:
             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,
-            panda1.packageName, panda1.version, panda2.version)
+            panda1.packageName, panda1.version, panda2.version))
         return False
 
     def __findPackageInRequires(self, packageName, list):
@@ -3188,7 +3245,9 @@ class Packager:
                                        requires = self.currentPackage.requires)
             if not package:
                 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)
 
@@ -3293,42 +3352,27 @@ class Packager:
         producing their own custom panda3d for download.  Should be
         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
         # start an application running.
         self.do_module('direct.p3d.AppRunner')
 
         # 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'):
             # On Mac, we package up a P3DPython.app bundle.  This
@@ -3411,7 +3455,7 @@ class Packager:
                 freezer.addModule(moduleName, newName = newName)
             else:
                 freezer.modules[newName] = freezer.modules[moduleName]
-        freezer.done(compileToExe = compileToExe)
+        freezer.done(addStartupModules = compileToExe)
 
         dirname = ''
         basename = filename
@@ -3604,6 +3648,43 @@ class Packager:
         filename = Filename(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):
 
         """ Adds the indicated directory hierarchy to the current
@@ -3676,7 +3757,12 @@ class Packager:
                     filename.setBinary()
                 self.currentPackage.addFile(filename, newName = newName,
                                             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):
         """ Reads the contents.xml file at the beginning of
@@ -3750,8 +3836,7 @@ class Packager:
                 xhost = he.makeXml(packager = self)
                 xcontents.InsertEndChild(xhost)
 
-        contents = self.contents.items()
-        contents.sort()
+        contents = sorted(self.contents.items())
         for key, pe in contents:
             xpackage = pe.makeXml()
             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.SeqValue import SeqValue
 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
 vfs = VirtualFileSystem.getGlobalPtr()
 

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

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

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

@@ -66,7 +66,7 @@ class images(package):
             token = '%s_img' % (name)
             configDict[token] = basename
         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
     # 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
      (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
      Adds a directory to search for additional Python modules.  You
      can use this to add your system's Python path, to allow packp3d
@@ -103,7 +111,7 @@ class ArgumentError(StandardError):
     pass
 
 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()
 
@@ -134,6 +142,8 @@ def makePackedApp(args):
             packager.binaryExtensions.append(value)
         elif option == '-n':
             packager.uncompressibleExtensions.append(value)
+        elif option == '-x':
+            packager.extractExtensions.append(value)
         elif option == '-p':
             sys.path.append(value)
         elif option == '-c':
@@ -154,10 +164,10 @@ def makePackedApp(args):
                 PandaSystem.getPackageHostUrl(),
                 os.path.split(sys.argv[0])[1],
                 '%s.%s' % (sys.version_info[0], sys.version_info[1]))
-            sys.exit(1)
+            sys.exit(0)
 
     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:
         raise ArgumentError, "Extra arguments on command line."
@@ -170,19 +180,20 @@ def makePackedApp(args):
       appDir = Filename('.')
     appBase = appFilename.getBasenameWoExtension()
 
-    if not main:
+    if main:
+        main = Filename.fromOsSpecific(main)
+        main.makeAbsolute(root)
+    else:
         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'))
             if len(main) == 0:
                 raise ArgumentError, 'No Python files in root directory.'
             elif len(main) > 1:
                 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.allowPythonDev = allowPythonDev

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

@@ -61,7 +61,7 @@ class panda3d(package):
            'panda3d.physics')
 
     # 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.mbcs', 'encodings.latin_1', 'io')
 
@@ -195,7 +195,7 @@ class morepy(package):
            'termios', 'tty', 'pty', 'fcntl', 'pipes', 'posixfile',
            'resource', 'nis', 'syslog', 'commands', 'ic', 'MacOS',
            'macostools', 'findertools', 'EasyDialogs', 'FrameWork',
-           'autoGIL', 'ColorPicker')
+           'autoGIL', 'ColorPicker', 'ast')
 
     # To add the multitude of standard Python string encodings.
     module('encodings', 'encodings.*')
@@ -362,8 +362,16 @@ class rocket(package):
     config(display_name = "Panda3D libRocket support")
     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)
 
 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
      of packages!
 
+  -v
+     Emit a warning for any file not recognized by the dir() command
+     (indicating there may be a need for addExtensions(...)).
+     
   -h
      Display this help
 """
@@ -135,12 +139,12 @@ from direct.p3d import Packager
 from panda3d.core import *
 
 def usage(code, msg = ''):
-    print >> sys.stderr, usageText % {
+    sys.stderr.write(usageText % {
         'version' : PandaSystem.getPackageVersionString(),
         'host' : PandaSystem.getPackageHostUrl(),
         'prog' : os.path.split(sys.argv[0])[1]
-        }
-    print >> sys.stderr, msg
+        })
+    sys.stderr.write(msg + '\n')
     sys.exit(code)
 
 installDir = None
@@ -151,12 +155,13 @@ allowPythonDev = False
 universalBinaries = False
 systemRoot = None
 ignoreSetHost = False
+verbosePrint = False
 p3dSuffix = ''
 platforms = []
 
 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)
 
 for opt, arg in opts:
@@ -188,10 +193,13 @@ for opt, arg in opts:
     elif opt == '-a':
         p3dSuffix = arg
 
+    elif opt == '-v':
+        verbosePrint = True
+        
     elif opt == '-h':
         usage(0)
     else:
-        print 'illegal option: ' + arg
+        print('illegal option: ' + arg)
         sys.exit(1)
 
 if not args:
@@ -212,7 +220,7 @@ else:
 
 if universalBinaries:
     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)
     if PandaSystem.getPlatform().startswith('osx_'):
         platforms = ['osx_i386', 'osx_amd64']
@@ -230,6 +238,7 @@ for platform in platforms:
     packager.allowPythonDev = allowPythonDev
     packager.systemRoot = systemRoot
     packager.ignoreSetHost = ignoreSetHost
+    packager.verbosePrint = verbosePrint
     packager.p3dSuffix = p3dSuffix
 
     try:
@@ -242,7 +251,7 @@ for platform in platforms:
     except Packager.PackagerError:
         # Just print the error message and exit gracefully.
         inst = sys.exc_info()[1]
-        print inst.args[0]
+        print(inst.args[0])
         sys.exit(1)
 
 # 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')
 
 class httplib2(package):
-    config(display_name = "httplib2")
+    config(display_name = "httplib2", platform_specific = False)
     require('panda3d')
 
     module('httplib2', required = True)
@@ -149,7 +149,7 @@ class box2d(package):
     module('Box2D', required = True)
 
 class pyglet(package):
-    config(display_name = "pyglet")
-    require('panda3d')
+    config(display_name = "pyglet", platform_specific = False)
+    require('panda3d', 'morepy')
 
     module('pyglet', required = True)

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません