Browse Source

Merge branch 'master' into interrogate-overhaul

Conflicts:
	dtool/src/interrogate/functionRemap.cxx
	dtool/src/interrogate/interfaceMakerPythonNative.cxx
	panda/src/event/pythonTask.cxx
	panda/src/express/multifile.h
	panda/src/express/pointerToArray.I
	panda/src/mathutil/config_mathutil.N
	panda/src/putil/config_util.N
	panda/src/putil/doubleBitMask.h
rdb 11 years ago
parent
commit
4dc4c9eb3d
100 changed files with 1906 additions and 1402 deletions
  1. 2 2
      .travis.yml
  2. 4 0
      direct/src/dcparser/dcPacker.cxx
  3. 1 1
      direct/src/dcparser/dcPacker.h
  4. 22 182
      direct/src/distributed/cConnectionRepository.cxx
  5. 3 17
      direct/src/distributed/cConnectionRepository.h
  6. 1 8
      dtool/LocalSetup.pp
  7. 4 1
      dtool/src/dtoolbase/atomicAdjustWin32Impl.h
  8. 44 2
      dtool/src/dtoolbase/cmath.I
  9. 2 0
      dtool/src/dtoolbase/cmath.h
  10. 6 1
      dtool/src/dtoolbase/dlmalloc.h
  11. 9 1
      dtool/src/dtoolbase/dlmalloc_src.cxx
  12. 9 0
      dtool/src/dtoolbase/dtoolbase.h
  13. 3 1
      dtool/src/dtoolbase/memoryHook.cxx
  14. 3 1
      dtool/src/dtoolbase/mutexWin32Impl.h
  15. 3 1
      dtool/src/dtoolbase/ptmalloc2_smp_src.cxx
  16. 3 1
      dtool/src/dtoolutil/pandaFileStreamBuf.h
  17. 3 1
      dtool/src/dtoolutil/pfstreamBuf.h
  18. 21 8
      dtool/src/interrogate/functionRemap.cxx
  19. 4 4
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  20. 16 0
      dtool/src/interrogate/interrogateBuilder.cxx
  21. 1 1
      dtool/src/interrogate/interrogate_module.cxx
  22. 166 70
      makepanda/makepanda.py
  23. 46 19
      panda/src/collide/collisionBox.cxx
  24. 1 1
      panda/src/display/Sources.pp
  25. 4 5
      panda/src/display/callbackGraphicsWindow.h
  26. 4 4
      panda/src/display/displayRegion.cxx
  27. 58 4
      panda/src/display/graphicsStateGuardian.cxx
  28. 2 1
      panda/src/display/graphicsStateGuardian.h
  29. 1 1
      panda/src/display/graphicsStateGuardian_ext.cxx
  30. 6 4
      panda/src/display/graphicsWindowProc.h
  31. 0 3
      panda/src/display/p3display_composite2.cxx
  32. 4 0
      panda/src/display/pythonGraphicsWindowProc.cxx
  33. 11 5
      panda/src/display/pythonGraphicsWindowProc.h
  34. 1 5
      panda/src/downloader/httpAuthorization.h
  35. 3 1
      panda/src/dxgsg9/dxgsg9base.h
  36. 4 4
      panda/src/dxml/config_dxml.h
  37. 14 14
      panda/src/dxml/tinyxml.h
  38. 2 2
      panda/src/egg/eggGroupNode_ext.cxx
  39. 119 0
      panda/src/egg/eggVertex.cxx
  40. 3 0
      panda/src/egg/eggVertex.h
  41. 20 5
      panda/src/egg/eggVertexAux.cxx
  42. 3 0
      panda/src/egg/eggVertexAux.h
  43. 31 6
      panda/src/egg/eggVertexUV.cxx
  44. 3 0
      panda/src/egg/eggVertexUV.h
  45. 29 28
      panda/src/egg2pg/eggLoader.cxx
  46. 1 2
      panda/src/event/Sources.pp
  47. 0 4
      panda/src/event/config_event.cxx
  48. 0 1
      panda/src/event/p3event_composite1.cxx
  49. 7 2
      panda/src/event/pythonTask.cxx
  50. 1 1
      panda/src/event/pythonTask.h
  51. 3 2
      panda/src/express/dcast.cxx
  52. 0 48
      panda/src/express/multifile.I
  53. 47 0
      panda/src/express/multifile.cxx
  54. 194 194
      panda/src/express/ordered_vector.I
  55. 51 51
      panda/src/express/ordered_vector.T
  56. 25 28
      panda/src/express/ordered_vector.h
  57. 3 2
      panda/src/express/password_hash.h
  58. 1 324
      panda/src/express/pointerToArray.I
  59. 9 71
      panda/src/express/pointerToArray.h
  60. 321 0
      panda/src/express/pointerToArray_ext.I
  61. 100 0
      panda/src/express/pointerToArray_ext.h
  62. 3 1
      panda/src/express/trueClock.cxx
  63. 2 1
      panda/src/express/virtualFileSystem_ext.cxx
  64. 3 1
      panda/src/express/windowsRegistry.cxx
  65. 99 39
      panda/src/glstuff/glCgShaderContext_src.cxx
  66. 5 0
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  67. 19 0
      panda/src/glstuff/glShaderContext_src.cxx
  68. 8 4
      panda/src/gobj/Sources.pp
  69. 1 1
      panda/src/gobj/geomVertexData.cxx
  70. 3 0
      panda/src/gobj/p3gobj_ext_composite.cxx
  71. 1 1
      panda/src/gobj/shader.I
  72. 9 3
      panda/src/gobj/shader.cxx
  73. 5 1
      panda/src/gobj/shader.h
  74. 3 3
      panda/src/gobj/texture.cxx
  75. 12 73
      panda/src/gobj/textureCollection.cxx
  76. 3 4
      panda/src/gobj/textureCollection.h
  77. 94 0
      panda/src/gobj/textureCollection_ext.cxx
  78. 42 0
      panda/src/gobj/textureCollection_ext.h
  79. 1 1
      panda/src/gobj/transformBlend.cxx
  80. 3 3
      panda/src/gobj/vertexDataPage.h
  81. 3 1
      panda/src/gobj/vertexDataSaveFile.h
  82. 6 6
      panda/src/linmath/lpoint2_ext_src.I
  83. 6 6
      panda/src/linmath/lpoint3_ext_src.I
  84. 6 6
      panda/src/linmath/lpoint4_ext_src.I
  85. 6 7
      panda/src/linmath/lvecBase2_ext_src.I
  86. 6 7
      panda/src/linmath/lvecBase3_ext_src.I
  87. 6 7
      panda/src/linmath/lvecBase4_ext_src.I
  88. 6 6
      panda/src/linmath/lvector2_ext_src.I
  89. 6 6
      panda/src/linmath/lvector3_ext_src.I
  90. 6 6
      panda/src/linmath/lvector4_ext_src.I
  91. 2 0
      panda/src/mathutil/config_mathutil.N
  92. 1 1
      panda/src/mathutil/triangulator.cxx
  93. 21 21
      panda/src/movies/microphoneAudioDS.cxx
  94. 5 1
      panda/src/nativenet/buffered_datagramconnection.h
  95. 1 1
      panda/src/net/connectionManager.h
  96. 13 13
      panda/src/ode/odeGeom_ext.cxx
  97. 12 12
      panda/src/ode/odeJoint_ext.cxx
  98. 4 4
      panda/src/ode/odeSpace_ext.cxx
  99. 11 9
      panda/src/ode/odeTriMeshData.h
  100. 1 1
      panda/src/parametrics/curveFitter.h

+ 2 - 2
.travis.yml

@@ -4,12 +4,12 @@ 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
+script: python makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT --installer
 notifications:
   irc:
     channels:
       - "chat.freenode.net#panda3d"
     on_success: change
-    on_failure: change
+    on_failure: always
     use_notice: true
     skip_join: true

+ 4 - 0
direct/src/dcparser/dcPacker.cxx

@@ -20,6 +20,10 @@
 #include "dcSwitchParameter.h"
 #include "dcClass.h"
 
+#ifdef HAVE_PYTHON
+#include "py_panda.h"
+#endif
+
 DCPacker::StackElement *DCPacker::StackElement::_deleted_chain = NULL;
 int DCPacker::StackElement::_num_ever_allocated = 0;
 

+ 1 - 1
direct/src/dcparser/dcPacker.h

@@ -220,7 +220,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
-  class StackElement {
+  class EXPCL_DIRECT StackElement {
   public:
     // As an optimization, we implement operator new and delete here
     // to minimize allocation overhead during push() and pop().

+ 22 - 182
direct/src/distributed/cConnectionRepository.cxx

@@ -26,11 +26,7 @@
 #include "pStatTimer.h"
 
 #ifdef HAVE_PYTHON
-#ifndef CPPPARSER
-#include "py_panda.h"  
-IMPORT_THIS struct   Dtool_PyTypedObject Dtool_DatagramIterator;
-IMPORT_THIS struct   Dtool_PyTypedObject Dtool_DCClass;
-#endif
+#include "py_panda.h"
 #endif
 
 const string CConnectionRepository::_overflow_event_name = "CRDatagramOverflow";
@@ -42,14 +38,13 @@ PStatCollector CConnectionRepository::_update_pcollector("App:Show code:readerPo
 ////////////////////////////////////////////////////////////////////
 //     Function: CConnectionRepository::Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 CConnectionRepository::
 CConnectionRepository(bool has_owner_view, bool threaded_net) :
   _lock("CConnectionRepository::_lock"),
 #ifdef HAVE_PYTHON
   _python_repository(NULL),
-  _python_ai_datagramiterator(NULL),
 #endif
 #ifdef HAVE_OPENSSL
   _http_conn(NULL),
@@ -82,19 +77,12 @@ CConnectionRepository(bool has_owner_view, bool threaded_net) :
   }
 #endif
   _tcp_header_size = tcp_header_size;
-
-#ifdef HAVE_PYTHON
-  PyObject *  PyDitterator = DTool_CreatePyInstance(&_di,Dtool_DatagramIterator,false,false);
-  if(PyDitterator != NULL)
-      _python_ai_datagramiterator = Py_BuildValue("(O)",PyDitterator);
-#endif
-
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: CConnectionRepository::Destructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 CConnectionRepository::
 ~CConnectionRepository() {
@@ -182,7 +170,7 @@ try_connect_net(const URLSpec &url) {
 
   disconnect();
 
-  _net_conn = 
+  _net_conn =
     _qcm.open_TCP_client_connection(url.get_server(), url.get_port(),
                                     game_server_timeout_ms);
 
@@ -315,7 +303,7 @@ check_datagram() {
         _msg_channels.push_back(schan);
       }
       _msg_sender = _di.get_uint64();
-      
+
 #ifdef HAVE_PYTHON
       // For now, we need to stuff this field onto the Python
       // structure, to support legacy code that expects to find it
@@ -361,7 +349,7 @@ check_datagram() {
       }
       break;
 #endif  // HAVE_PYTHON
-      
+
     default:
       // Some unknown message; let the caller deal with it.
       return true;
@@ -372,9 +360,6 @@ check_datagram() {
   return false;
 }
 
-
-
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CConnectionRepository::is_connected
 //       Access: Published
@@ -745,7 +730,7 @@ handle_update_field() {
 
   PStatTimer timer(_update_pcollector);
   unsigned int do_id = _di.get_uint32();
-  if (_python_repository != (PyObject *)NULL) 
+  if (_python_repository != (PyObject *)NULL)
   {
     PyObject *doId2do =
       PyObject_GetAttrString(_python_repository, "doId2do");
@@ -794,9 +779,9 @@ handle_update_field() {
       // method might get into trouble if it tried to delete the
       // object from the doId2do map.
       Py_INCREF(distobj);
-      dclass->receive_update(distobj, _di); 
+      dclass->receive_update(distobj, _di);
       Py_DECREF(distobj);
-      
+
       if (PyErr_Occurred()) {
 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
         PyGILState_Release(gstate);
@@ -810,7 +795,7 @@ handle_update_field() {
 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
   PyGILState_Release(gstate);
 #endif
-  #endif  // HAVE_PYTHON  
+  #endif  // HAVE_PYTHON
   return true;
 }
 
@@ -880,9 +865,9 @@ handle_update_field_owner() {
         // make a copy of the datagram iterator so that we can use the main
         // iterator for the non-owner update
         DatagramIterator _odi(_di);
-        dclass->receive_update(distobjOV, _odi); 
+        dclass->receive_update(distobjOV, _odi);
         Py_DECREF(distobjOV);
-      
+
         if (PyErr_Occurred()) {
 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
           PyGILState_Release(gstate);
@@ -919,9 +904,9 @@ handle_update_field_owner() {
         // method might get into trouble if it tried to delete the
         // object from the doId2do map.
         Py_INCREF(distobj);
-        dclass->receive_update(distobj, _di); 
+        dclass->receive_update(distobj, _di);
         Py_DECREF(distobj);
-      
+
         if (PyErr_Occurred()) {
 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
           PyGILState_Release(gstate);
@@ -935,7 +920,7 @@ handle_update_field_owner() {
 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
   PyGILState_Release(gstate);
 #endif
-#endif  // HAVE_PYTHON  
+#endif  // HAVE_PYTHON
 
   return true;
 }
@@ -948,17 +933,17 @@ handle_update_field_owner() {
 //               output stream.
 ////////////////////////////////////////////////////////////////////
 void CConnectionRepository::
-describe_message(ostream &out, const string &prefix, 
+describe_message(ostream &out, const string &prefix,
                  const Datagram &dg) const {
   DCPacker packer;
-  
+
   packer.set_unpack_data(dg.get_message());
   CHANNEL_TYPE do_id;
   int msg_type;
   bool is_update = false;
   string full_prefix = "CR::" + prefix;
 
-  if (!_client_datagram) 
+  if (!_client_datagram)
   {
     unsigned char mcnt = packer.raw_unpack_uint8();
     for( ;mcnt > 0; mcnt--)
@@ -967,7 +952,7 @@ describe_message(ostream &out, const string &prefix,
     packer.RAW_UNPACK_CHANNEL();  // msg_sender
     msg_type = packer.raw_unpack_uint16();
     is_update = (msg_type == STATESERVER_OBJECT_UPDATE_FIELD);
-    
+
   } else {
     msg_type = packer.raw_unpack_uint16();
     is_update = (msg_type == CLIENT_OBJECT_UPDATE_FIELD);
@@ -1045,12 +1030,12 @@ describe_message(ostream &out, const string &prefix,
         Py_DECREF(dclass_this);
       }
     }
-    #endif  // HAVE_PYTHON  
+    #endif  // HAVE_PYTHON
 
     int field_id = packer.raw_unpack_uint16();
 
     if (dclass == (DCClass *)NULL) {
-      out << full_prefix << "update for unknown object " << do_id 
+      out << full_prefix << "update for unknown object " << do_id
           << ", field " << field_id << "\n";
 
     } else {
@@ -1059,7 +1044,7 @@ describe_message(ostream &out, const string &prefix,
       DCField *field = dclass->get_field_by_index(field_id);
       if (field == (DCField *)NULL) {
         out << "unknown field " << field_id << "\n";
-        
+
       } else {
         out << field->get_name();
         packer.begin_unpack(field);
@@ -1070,148 +1055,3 @@ describe_message(ostream &out, const string &prefix,
     }
   }
 }
-
-
-
-
-#ifdef HAVE_PYTHON
-#ifdef WANT_NATIVE_NET
-
-bool CConnectionRepository::network_based_reader_and_yielder(PyObject *PycallBackFunction,ClockObject &clock, float returnBy)
-{
-  ReMutexHolder holder(_lock);
-    while(is_connected())
-    {        
-        check_datagram_ai(PycallBackFunction);
-        if(is_connected())
-            _bdc.Flush();
-        float currentTime = clock.get_real_time();
-        float dif_time = returnBy - currentTime;
-        if(dif_time <= 0.001) // to avoi over runs..
-            break;
-        if(is_connected())
-            _bdc.WaitForNetworkReadEvent(dif_time);
-    }
-    return false;
-}
-
-bool CConnectionRepository::check_datagram_ai(PyObject *PycallBackFunction)
-{
-  ReMutexHolder holder(_lock);
-    // these could be static .. not 
-  PyObject *doId2do = NULL; 
-  float startTime =0;
-  float endTime = 0;
-  // this seems weird...here
-  _bdc.Flush();
-  while (_bdc.GetMessage(_dg))
-  { 
-      if (get_verbose()) 
-          describe_message(nout, "RECV", _dg);
-
-      if (_time_warning > 0) 
-        startTime = ClockObject::get_global_clock()->get_real_time();
-
-      // Start breaking apart the datagram.
-      _di.assign(_dg);
-      unsigned char  wc_cnt = _di.get_uint8();
-      _msg_channels.clear();
-      for(unsigned char lp1 = 0; lp1 < wc_cnt; lp1++)
-          _msg_channels.push_back(_di.get_uint64());
-
-      _msg_sender = _di.get_uint64();
-      _msg_type = _di.get_uint16();
-
-      if( _msg_type == STATESERVER_OBJECT_UPDATE_FIELD)
-      {
-          if(doId2do == NULL)
-          {
-              // this is my attemp to take it out of the inner loop  RHH
-              doId2do =PyObject_GetAttrString(_python_repository, "doId2do");
-              nassertr(doId2do != NULL, false);
-          }
-
-          if (!handle_update_field_ai(doId2do)) 
-          {
-              Py_XDECREF(doId2do);
-              if (_time_warning > 0) {
-                endTime = ClockObject::get_global_clock()->get_real_time(); 
-                if ( _time_warning < (endTime - startTime)) {
-                  nout << "msg " << _msg_type <<" from " << _msg_sender << " took "<<  (endTime-startTime) << "secs to process\n";
-                  _dg.dump_hex(nout,2);
-                }
-              }
-              return false; 
-          }
-      }
-      else
-      {
-          PyObject * result = PyEval_CallObject(PycallBackFunction, _python_ai_datagramiterator);
-          if (PyErr_Occurred()) 
-          {        
-              Py_XDECREF(doId2do);
-              if (_time_warning > 0) {
-                endTime = ClockObject::get_global_clock()->get_real_time(); 
-                if ( _time_warning < (endTime - startTime)) {
-                  nout << "msg " << _msg_type <<" from " << _msg_sender << " took "<<  (endTime-startTime) << "secs to process\n";
-                  _dg.dump_hex(nout,2);                
-                }
-              }
-              return true;
-          }
-      }
-
-      if (_time_warning > 0) {
-        endTime = ClockObject::get_global_clock()->get_real_time(); 
-        if ( _time_warning < (endTime - startTime)) {
-          nout << "msg " << _msg_type <<" from " << _msg_sender << " took "<<  (endTime-startTime) << "secs to process\n";
-          _dg.dump_hex(nout,2);   
-        }
-      }
-             
-  }
-
-
-  Py_XDECREF(doId2do);
-  return false;
-}
-
-#endif  // #ifdef WANT_NATIVE_NET
-#endif  // #ifdef HAVE_PYTHON
-
-
-#ifdef HAVE_PYTHON
-#ifdef WANT_NATIVE_NET
-
-
-bool CConnectionRepository::handle_update_field_ai(PyObject *doId2do) 
-{
-  PStatTimer timer(_update_pcollector);
-  unsigned int do_id = _di.get_uint32();
- 
-  PyObject *doId = PyLong_FromUnsignedLong(do_id);
-  PyObject *distobj = PyDict_GetItem(doId2do, doId);
-  Py_DECREF(doId);
-
-  if (distobj != NULL)
-  {
-      PyObject *dclass_obj = PyObject_GetAttrString(distobj, "dclass");
-      nassertr(dclass_obj != NULL, false);
-
-      DCClass *dclass = NULL;
-      DTOOL_Call_ExtractThisPointerForType(dclass_obj, &Dtool_DCClass, (void **) &dclass);
-      if(dclass == NULL)
-          return false;
-
-      Py_INCREF(distobj);
-      dclass->receive_update(distobj, _di); 
-      Py_DECREF(distobj);
-
-      if (PyErr_Occurred()) 
-          return false;
-  }
-  return true;
-}
-
-#endif  // #ifdef WANT_NATIVE_NET
-#endif  // #ifdef HAVE_PYTHON

+ 3 - 17
direct/src/distributed/cConnectionRepository.h

@@ -100,7 +100,7 @@ PUBLISHED:
 #endif
 #ifdef HAVE_NET
   BLOCKING bool try_connect_net(const URLSpec &url);
-  
+
   INLINE QueuedConnectionManager &get_qcm();
   INLINE ConnectionWriter &get_cw();
   INLINE QueuedConnectionReader &get_qcr();
@@ -117,13 +117,7 @@ PUBLISHED:
 #endif
 
   BLOCKING bool check_datagram();
-#ifdef HAVE_PYTHON
-#ifdef WANT_NATIVE_NET
-  BLOCKING bool check_datagram_ai(PyObject *PycallBackFunction);
-  BLOCKING bool network_based_reader_and_yielder(PyObject *PycallBackFunction,ClockObject &clock, float returnBy);
-#endif
-#endif
-    
+
   BLOCKING INLINE void get_datagram(Datagram &dg);
   BLOCKING INLINE void get_datagram_iterator(DatagramIterator &di);
   BLOCKING INLINE CHANNEL_TYPE get_msg_channel(int offset = 0) const;
@@ -167,18 +161,11 @@ PUBLISHED:
   INLINE float get_time_warning() const;
 
 private:
-#ifdef HAVE_PYTHON
-#ifdef WANT_NATIVE_NET
-    bool handle_update_field_ai(PyObject *doId2do);
-#endif
-#endif
-
-
   bool do_check_datagram();
   bool handle_update_field();
   bool handle_update_field_owner();
 
-  void describe_message(ostream &out, const string &prefix, 
+  void describe_message(ostream &out, const string &prefix,
                         const Datagram &dg) const;
 
 private:
@@ -186,7 +173,6 @@ private:
 
 #ifdef HAVE_PYTHON
   PyObject *_python_repository;
-  PyObject *_python_ai_datagramiterator;
 #endif
 
 #ifdef HAVE_OPENSSL

+ 1 - 8
dtool/LocalSetup.pp

@@ -382,19 +382,12 @@ $[cdefine USE_GENERIC_DXERR_LIBRARY]
 /* Define if we have zlib installed.  */
 $[cdefine HAVE_ZLIB]
 
-/* Define if we have OpenGL installed and want to build for GL.  */
-$[cdefine HAVE_GL]
+/* Define the preconfigured minimum GL version number.  */
 #if HAVE_GL
 # define MIN_GL_VERSION_MAJOR $[word 1,$[MIN_GL_VERSION]]
 # define MIN_GL_VERSION_MINOR $[word 2,$[MIN_GL_VERSION]]
 #endif
 
-/* Define if we have OpenGL ES installed and want to build for GLES. */
-$[cdefine HAVE_GLES]
-
-/* Define if we have OpenGL ES installed and want to build for GLES2. */
-$[cdefine HAVE_GLES2]
-
 /* Define if we have OpenCV installed and want to build for OpenCV.  */
 $[cdefine HAVE_OPENCV]
 $[cdefine OPENCV_VER_23]

+ 4 - 1
dtool/src/dtoolbase/atomicAdjustWin32Impl.h

@@ -21,7 +21,10 @@
 #ifdef WIN32_VC
 
 #include "numeric_types.h"
-#define WIN32_LEAN_AND_MEAN
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 ////////////////////////////////////////////////////////////////////

+ 44 - 2
dtool/src/dtoolbase/cmath.I

@@ -358,26 +358,68 @@ cpow(int x, int y) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: cnan
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool
+cnan(float v) {
+#if __FINITE_MATH_ONLY__
+  // GCC's isnan breaks when using -ffast-math.
+  union { float f; uint32_t x; } u = { v };
+  return ((u.x << 1) > 0xff000000u);
+#elif !defined(_WIN32)
+  return std::isnan(v);
+#else
+  return (_isnan(v) != 0);
+#endif
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: cnan
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE bool
 cnan(double v) {
-#ifndef _WIN32
+#if __FINITE_MATH_ONLY__
+  // GCC's isnan breaks when using -ffast-math.
+  union { double d; uint64_t x; } u = { v };
+  return ((u.x << 1) > 0xff70000000000000ull);
+#elif !defined(_WIN32)
   return std::isnan(v);
 #else
   return (_isnan(v) != 0);
 #endif
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: cinf
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool
+cinf(float v) {
+#if __FINITE_MATH_ONLY__
+  // GCC's isinf breaks when using -ffast-math.
+  union { float f; uint32_t x; } u = { v };
+  return ((u.x << 1) == 0xff000000u);
+#elif !defined(_WIN32)
+  return std::isinf(v);
+#else
+  return (_isnan(v) == 0 && _finite(v) == 0);
+#endif
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: cinf
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE bool
 cinf(double v) {
-#ifndef _WIN32
+#if __FINITE_MATH_ONLY__
+  // GCC's isinf breaks when using -ffast-math.
+  union { double d; uint64_t x; } u = { v };
+  return ((u.x << 1) == 0xff70000000000000ull);
+#elif !defined(_WIN32)
   return std::isinf(v);
 #else
   return (_isnan(v) == 0 && _finite(v) == 0);

+ 2 - 0
dtool/src/dtoolbase/cmath.h

@@ -61,9 +61,11 @@ INLINE int cpow(int x, int y);
 
 // Returns true if the number is NaN, false if it's a genuine number
 // or infinity.
+INLINE bool cnan(float v);
 INLINE bool cnan(double v);
 
 // Returns true if the number is infinity.
+INLINE bool cinf(float v);
 INLINE bool cinf(double v);
 
 // Return NaN and infinity, respectively.

+ 6 - 1
dtool/src/dtoolbase/dlmalloc.h

@@ -148,10 +148,15 @@ void* dlvalloc(size_t);
 */
 int dlmallopt(int, int);
 
+#ifndef M_TRIM_THRESHOLD
 #define M_TRIM_THRESHOLD     (-1)
+#endif
+#ifndef M_GRANULARITY
 #define M_GRANULARITY        (-2)
+#endif
+#ifndef M_MMAP_THRESHOLD
 #define M_MMAP_THRESHOLD     (-3)
-
+#endif
 
 /*
   malloc_footprint();

+ 9 - 1
dtool/src/dtoolbase/dlmalloc_src.cxx

@@ -462,7 +462,9 @@ DEFAULT_MMAP_THRESHOLD       default: 256K
 #endif  /* _WIN32 */
 #endif  /* WIN32 */
 #ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 #define HAVE_MMAP 1
 #define HAVE_MORECORE 0
@@ -597,9 +599,15 @@ DEFAULT_MMAP_THRESHOLD       default: 256K
   malloc does support the following options.
 */
 
+#ifndef M_TRIM_THRESHOLD
 #define M_TRIM_THRESHOLD     (-1)
+#endif
+#ifndef M_GRANULARITY
 #define M_GRANULARITY        (-2)
+#endif
+#ifndef M_MMAP_THRESHOLD
 #define M_MMAP_THRESHOLD     (-3)
+#endif
 
 /* ------------------------ Mallinfo declarations ------------------------ */
 

+ 9 - 0
dtool/src/dtoolbase/dtoolbase.h

@@ -103,6 +103,15 @@
 #endif
 #endif
 
+// This is a workaround for a glibc bug that is triggered by
+// clang when compiling with -ffast-math.
+#ifdef __clang__
+#include <sys/cdefs.h>
+#ifndef __extern_always_inline
+#define __extern_always_inline extern __always_inline
+#endif
+#endif
+
 #ifdef HAVE_PYTHON
 #undef _POSIX_C_SOURCE
 #undef _XOPEN_SOURCE

+ 3 - 1
dtool/src/dtoolbase/memoryHook.cxx

@@ -19,7 +19,9 @@
 #ifdef WIN32
 
 // Windows case.
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 #else

+ 3 - 1
dtool/src/dtoolbase/mutexWin32Impl.h

@@ -19,7 +19,9 @@
 #include "selectThreadImpl.h"
 
 #ifdef WIN32_VC
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 1
dtool/src/dtoolbase/ptmalloc2_smp_src.cxx

@@ -482,7 +482,9 @@ int tsd_key_next;
 #elif defined(WIN32)
 /* Win32 emulation */
 
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #define _WIN32_WINNT 0x600
 #include <windows.h>
 

+ 3 - 1
dtool/src/dtoolutil/pandaFileStreamBuf.h

@@ -20,7 +20,9 @@
 #ifdef USE_PANDAFILESTREAM
 
 #if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 #endif
 

+ 3 - 1
dtool/src/dtoolutil/pfstreamBuf.h

@@ -28,7 +28,9 @@
 #endif
 
 #ifdef WIN_PIPE_CALLS
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 #else  // WIN_PIPE_CALLS

+ 21 - 8
dtool/src/interrogate/functionRemap.cxx

@@ -162,6 +162,18 @@ call_function(ostream &out, int indent_level, bool convert_result,
     string defconstruct = builder.in_defconstruct(_cpptype->get_local_name(&parser));
     if (pexprs.empty() && !defconstruct.empty()) {
       return_expr = defconstruct;
+    } else if (_extension) {
+      // Extension constructors are a special case.  We assume there is a
+      // default constructor for the class, and the actual construction is
+      // done by an __init__ method.
+      InterfaceMaker::indent(out, indent_level);
+      _return_type->get_new_type()->output_instance(out, "result", &parser);
+      out << " = new " << _cpptype->get_local_name(&parser) << ";\n";
+
+      InterfaceMaker::indent(out, indent_level)
+        << get_call_str("result", pexprs) << ";\n";
+
+      return_expr = "result";
     } else {
       return_expr = "new " + get_call_str(container, pexprs);
     }
@@ -329,7 +341,7 @@ make_wrapper_entry(FunctionIndex function_index) {
       // understands that if the destructor function is zero, it
       // should use the regular class destructor.
 
-      //          nout << "Warning!  Destructor for " 
+      //          nout << "Warning!  Destructor for "
       //               << *_return_type->get_orig_type()
       //               << " is unavailable.\n"
       //               << "  Cannot manage return value for:\n  "
@@ -385,11 +397,13 @@ get_call_str(const string &container, const vector_string &pexprs) const {
         call << "Extension<" << _cpptype->get_local_name(&parser) << ">::";
       }
 
-      call << _cppfunc->get_local_name();
-      call << "(";
-
+      if (_type == T_constructor) {
+        // Constructor extensions are named __init__, by convention.
+        call << "__init__";
+      } else {
+        call << _cppfunc->get_local_name();
+      }
     } else {
-
       if (_type == T_constructor) {
         // Constructors are called differently.
         call << _cpptype->get_local_name(&parser);
@@ -402,9 +416,8 @@ get_call_str(const string &container, const vector_string &pexprs) const {
       } else {
         call << _cppfunc->get_local_name(&parser);
       }
-
-      call << "(";
     }
+    call << "(";
 
     if (_flags & F_explicit_self) {
       // Pass on the PyObject * that we stripped off above.
@@ -690,7 +703,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
   }
 
   if (_has_this || _type == T_constructor) {
-    if ((int)_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
+    if (_parameters.size() > (size_t)first_param && _parameters[first_param]._name == "self" &&
         TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
       // Here's a special case.  If the first parameter of a nonstatic
       // method is a PyObject * called "self", then we will

+ 4 - 4
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -3413,7 +3413,7 @@ write_function_instance(ostream &out,
           << "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
           << "#endif\n";
 
-        pexpr_string = "basic_string<wchar_t>(" +
+        pexpr_string = "std::wstring(" +
           param_name + "_str, " + param_name + "_len)";
 
         extra_cleanup
@@ -3439,7 +3439,7 @@ write_function_instance(ostream &out,
           << "PyUnicode_AsWideChar(" << param_name << ", " << param_name << "_str, " << param_name << "_len);\n"
           << "#endif\n";
 
-        pexpr_string = "&basic_string<wchar_t>(" +
+        pexpr_string = "&std::wstring(" +
           param_name + "_str, " + param_name + "_len)";
 
         extra_cleanup
@@ -3473,10 +3473,10 @@ write_function_instance(ostream &out,
         }
 
         if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
-          pexpr_string = "&basic_string<char>(" +
+          pexpr_string = "&std::string(" +
             param_name + "_str, " + param_name + "_len)";
         } else {
-          pexpr_string = "basic_string<char>(" +
+          pexpr_string = "std::string(" +
             param_name + "_str, " + param_name + "_len)";
         }
         expected_params += "str";

+ 16 - 0
dtool/src/interrogate/interrogateBuilder.cxx

@@ -214,6 +214,22 @@ do_command(const string &command, const string &params) {
   } else if (command == "noinclude") {
     insert_param_list(_noinclude, params);
 
+  } else if (command == "forceinclude") {
+    size_t nchars = params.size();
+    if (nchars >= 2 && params[0] == '"' && params[nchars-1] == '"') {
+      string incfile = params.substr(1, nchars - 2);
+      _include_files[incfile] = '"';
+
+    } else if (nchars >= 2 && params[0] == '<' && params[nchars-1] == '>') {
+      string incfile = params.substr(1, nchars - 2);
+      _include_files[incfile] = '<';
+
+    } else {
+      nout << "Ignoring invalid forceinclude " << params << "\n"
+              "Expected to be in one of the following forms:\n"
+              "  forceinclude \"file.h\"\n"
+              "  forceinclude <file.h>\n";
+    }
   } else {
     nout << "Ignoring " << command << " " << params << "\n";
   }

+ 1 - 1
dtool/src/interrogate/interrogate_module.cxx

@@ -112,7 +112,7 @@ int write_python_table_native(ostream &out) {
   pset<std::string >::iterator ii;
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     printf("Referencing Library %s\n", (*ii).c_str());
-    out << "IMPORT_THIS LibraryDef " << *ii << "_moddef;\n";
+    out << "extern LibraryDef " << *ii << "_moddef;\n";
   }
 
   out << "\n"

+ 166 - 70
makepanda/makepanda.py

@@ -981,6 +981,9 @@ def CompileCxx(obj,src,opts):
             else:
                 cmd += " -D_HAS_EXCEPTIONS=0"
 
+            if 'RTTI' not in opts:
+                 cmd += " /GR-"
+
             if GetTargetArch() == 'x64':
                 cmd += " /DWIN64_VC /DWIN64"
 
@@ -1104,6 +1107,8 @@ def CompileCxx(obj,src,opts):
         arch = GetTargetArch()
 
         if GetTarget() == "android":
+            # Most of the specific optimization flags here were
+            # just copied from the default Android Makefiles.
             cmd += ' -I%s/include' % (SDK["ANDROID_STL"])
             cmd += ' -I%s/libs/%s/include' % (SDK["ANDROID_STL"], SDK["ANDROID_ABI"])
             cmd += ' -ffunction-sections -funwind-tables'
@@ -1158,6 +1163,12 @@ def CompileCxx(obj,src,opts):
         if PkgSkip("SSE2") == 0 and not arch.startswith("arm"):
             cmd += " -msse2"
 
+        if optlevel >= 3:
+            cmd += " -ffast-math"
+        if optlevel == 3:
+            # Fast math is nice, but we'd like to see NaN in dev builds.
+            cmd += " -fno-finite-math-only"
+
         if (optlevel==1): cmd += " -ggdb -D_DEBUG"
         if (optlevel==2): cmd += " -O1 -D_DEBUG"
         if (optlevel==3): cmd += " -O2"
@@ -1292,8 +1303,8 @@ def CompileIgate(woutd,wsrc,opts):
         if (opt=="ALWAYS") or (opt in opts):
             cmd += ' -D' + var + '=' + val
 
-    building = GetValueOption(opts, "BUILDING:")
-    if (building): cmd += " -DBUILDING_"+building
+    #building = GetValueOption(opts, "BUILDING:")
+    #if (building): cmd += " -DBUILDING_"+building
     cmd += ' -module ' + module + ' -library ' + library
     for x in wsrc:
         if (x.startswith("/")):
@@ -1518,6 +1529,10 @@ def CompileLink(dll, obj, opts):
             else:
                 cmd = cxx + ' -shared'
                 if ("MODULE" not in opts): cmd += " -Wl,-soname=" + os.path.basename(dll)
+                if GetOrigExt(dll) == ".pyd" and not os.path.basename(dll).startswith('core'):
+                    # Tell the other libraries where to find core.so.
+                    # Not sure if this is the best way to do that, but it works.
+                    cmd += " -Wl,-rpath '-Wl,$ORIGIN'"
                 cmd += ' -o ' + dll + ' -L' + GetOutputDir() + '/lib -L' + GetOutputDir() + '/tmp'
 
         for x in obj:
@@ -1947,9 +1962,6 @@ DTOOL_CONFIG=[
     ("USE_PANDAFILESTREAM",            '1',                      '1'),
     ("USE_DELETED_CHAIN",              '1',                      '1'),
     ("HAVE_WIN_TOUCHINPUT",            'UNDEF',                  'UNDEF'),
-    ("HAVE_GL",                        '1',                      'UNDEF'),
-    ("HAVE_GLES",                      'UNDEF',                  'UNDEF'),
-    ("HAVE_GLES2",                     'UNDEF',                  'UNDEF'),
     ("HAVE_GLX",                       'UNDEF',                  '1'),
     ("HAVE_EGL",                       'UNDEF',                  'UNDEF'),
     ("HAVE_WGL",                       '1',                      'UNDEF'),
@@ -2938,6 +2950,7 @@ TargetAdd('libp3dtoolconfig.dll', input='libp3dtool.dll')
 TargetAdd('libp3dtoolconfig.dll', opts=['ADVAPI', 'OPENSSL', 'WINGDI', 'WINUSER'])
 
 if not PkgSkip("PYTHON"):
+  OPTS=['DIR:dtool/metalibs/dtoolconfig']
   TargetAdd('dtoolconfig_pydtool.obj', opts=OPTS, input="pydtool.cxx")
   TargetAdd('dtoolconfig.pyd', input='dtoolconfig_pydtool.obj')
   TargetAdd('dtoolconfig.pyd', input='libp3dtoolconfig.dll')
@@ -3017,11 +3030,13 @@ TargetAdd('p3pandabase_pandabase.obj', opts=OPTS, input='pandabase.cxx')
 OPTS=['DIR:panda/src/express', 'BUILDING:PANDAEXPRESS', 'OPENSSL', 'ZLIB']
 TargetAdd('p3express_composite1.obj', opts=OPTS, input='p3express_composite1.cxx')
 TargetAdd('p3express_composite2.obj', opts=OPTS, input='p3express_composite2.cxx')
-TargetAdd('p3express_ext_composite.obj', opts=OPTS, input='p3express_ext_composite.cxx')
+
+OPTS=['DIR:panda/src/express', 'OPENSSL', 'ZLIB']
 IGATEFILES=GetDirectoryContents('panda/src/express', ["*.h", "*_composite*.cxx"])
 TargetAdd('libp3express.in', opts=OPTS, input=IGATEFILES)
 TargetAdd('libp3express.in', opts=['IMOD:panda3d.core', 'ILIB:libp3express', 'SRCDIR:panda/src/express'])
 TargetAdd('libp3express_igate.obj', input='libp3express.in', opts=["DEPENDENCYONLY"])
+TargetAdd('p3express_ext_composite.obj', opts=OPTS, input='p3express_ext_composite.cxx')
 
 #
 # DIRECTORY: panda/src/downloader/
@@ -3030,6 +3045,8 @@ TargetAdd('libp3express_igate.obj', input='libp3express.in', opts=["DEPENDENCYON
 OPTS=['DIR:panda/src/downloader', 'BUILDING:PANDAEXPRESS', 'OPENSSL', 'ZLIB']
 TargetAdd('p3downloader_composite1.obj', opts=OPTS, input='p3downloader_composite1.cxx')
 TargetAdd('p3downloader_composite2.obj', opts=OPTS, input='p3downloader_composite2.cxx')
+
+OPTS=['DIR:panda/src/downloader', 'OPENSSL', 'ZLIB']
 IGATEFILES=GetDirectoryContents('panda/src/downloader', ["*.h", "*_composite*.cxx"])
 TargetAdd('libp3downloader.in', opts=OPTS, input=IGATEFILES)
 TargetAdd('libp3downloader.in', opts=['IMOD:panda3d.core', 'ILIB:libp3downloader', 'SRCDIR:panda/src/downloader'])
@@ -3044,11 +3061,8 @@ TargetAdd('pandaexpress_pandaexpress.obj', opts=OPTS, input='pandaexpress.cxx')
 TargetAdd('libpandaexpress.dll', input='pandaexpress_pandaexpress.obj')
 TargetAdd('libpandaexpress.dll', input='p3downloader_composite1.obj')
 TargetAdd('libpandaexpress.dll', input='p3downloader_composite2.obj')
-TargetAdd('libpandaexpress.dll', input='libp3downloader_igate.obj')
 TargetAdd('libpandaexpress.dll', input='p3express_composite1.obj')
 TargetAdd('libpandaexpress.dll', input='p3express_composite2.obj')
-TargetAdd('libpandaexpress.dll', input='p3express_ext_composite.obj')
-TargetAdd('libpandaexpress.dll', input='libp3express_igate.obj')
 TargetAdd('libpandaexpress.dll', input='p3pandabase_pandabase.obj')
 TargetAdd('libpandaexpress.dll', input=COMMON_DTOOL_LIBS)
 TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2',  'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER'])
@@ -3062,6 +3076,8 @@ if (not RUNTIME):
   TargetAdd('p3pipeline_composite1.obj', opts=OPTS, input='p3pipeline_composite1.cxx')
   TargetAdd('p3pipeline_composite2.obj', opts=OPTS, input='p3pipeline_composite2.cxx')
   TargetAdd('p3pipeline_contextSwitch.obj', opts=OPTS, input='contextSwitch.c')
+
+  OPTS=['DIR:panda/src/pipeline']
   IGATEFILES=GetDirectoryContents('panda/src/pipeline', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pipeline.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pipeline.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pipeline', 'SRCDIR:panda/src/pipeline'])
@@ -3075,6 +3091,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/linmath', 'BUILDING:PANDA']
   TargetAdd('p3linmath_composite1.obj', opts=OPTS, input='p3linmath_composite1.cxx')
   TargetAdd('p3linmath_composite2.obj', opts=OPTS, input='p3linmath_composite2.cxx')
+
+  OPTS=['DIR:panda/src/linmath']
   IGATEFILES=GetDirectoryContents('panda/src/linmath', ["*.h", "*_composite*.cxx"])
   for ifile in IGATEFILES[:]:
       if "_src." in ifile:
@@ -3094,12 +3112,15 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/putil', 'BUILDING:PANDA',  'ZLIB']
   TargetAdd('p3putil_composite1.obj', opts=OPTS, input='p3putil_composite1.cxx')
   TargetAdd('p3putil_composite2.obj', opts=OPTS, input='p3putil_composite2.cxx')
+
+  OPTS=['DIR:panda/src/putil', 'ZLIB']
   IGATEFILES=GetDirectoryContents('panda/src/putil', ["*.h", "*_composite*.cxx"])
   IGATEFILES.remove("test_bam.h")
   TargetAdd('libp3putil.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3putil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3putil', 'SRCDIR:panda/src/putil'])
   TargetAdd('libp3putil_igate.obj', input='libp3putil.in', opts=["DEPENDENCYONLY"])
   TargetAdd('p3putil_typedWritable_ext.obj', opts=OPTS, input='typedWritable_ext.cxx')
+  TargetAdd('p3putil_pythonCallbackObject.obj', opts=OPTS, input='pythonCallbackObject.cxx')
 
 #
 # DIRECTORY: panda/src/audio/
@@ -3108,6 +3129,8 @@ if (not RUNTIME):
 if (not RUNTIME):
   OPTS=['DIR:panda/src/audio', 'BUILDING:PANDA']
   TargetAdd('p3audio_composite1.obj', opts=OPTS, input='p3audio_composite1.cxx')
+
+  OPTS=['DIR:panda/src/audio']
   IGATEFILES=["audio.h"]
   TargetAdd('libp3audio.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3audio.in', opts=['IMOD:panda3d.core', 'ILIB:libp3audio', 'SRCDIR:panda/src/audio'])
@@ -3121,6 +3144,9 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/event', 'BUILDING:PANDA']
   TargetAdd('p3event_composite1.obj', opts=OPTS, input='p3event_composite1.cxx')
   TargetAdd('p3event_composite2.obj', opts=OPTS, input='p3event_composite2.cxx')
+
+  OPTS=['DIR:panda/src/event']
+  TargetAdd('p3event_pythonTask.obj', opts=OPTS, input='pythonTask.cxx')
   IGATEFILES=GetDirectoryContents('panda/src/event', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3event.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3event.in', opts=['IMOD:panda3d.core', 'ILIB:libp3event', 'SRCDIR:panda/src/event'])
@@ -3134,6 +3160,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/mathutil', 'BUILDING:PANDA', 'FFTW']
   TargetAdd('p3mathutil_composite1.obj', opts=OPTS, input='p3mathutil_composite1.cxx')
   TargetAdd('p3mathutil_composite2.obj', opts=OPTS, input='p3mathutil_composite2.cxx')
+
+  OPTS=['DIR:panda/src/mathutil', 'FFTW']
   IGATEFILES=GetDirectoryContents('panda/src/mathutil', ["*.h", "*_composite*.cxx"])
   for ifile in IGATEFILES[:]:
       if "_src." in ifile:
@@ -3149,6 +3177,8 @@ if (not RUNTIME):
 if (not RUNTIME):
   OPTS=['DIR:panda/src/gsgbase', 'BUILDING:PANDA']
   TargetAdd('p3gsgbase_composite1.obj', opts=OPTS, input='p3gsgbase_composite1.cxx')
+
+  OPTS=['DIR:panda/src/gsgbase']
   IGATEFILES=GetDirectoryContents('panda/src/gsgbase', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3gsgbase.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3gsgbase.in', opts=['IMOD:panda3d.core', 'ILIB:libp3gsgbase', 'SRCDIR:panda/src/gsgbase'])
@@ -3162,6 +3192,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/pnmimage', 'BUILDING:PANDA',  'ZLIB']
   TargetAdd('p3pnmimage_composite1.obj', opts=OPTS, input='p3pnmimage_composite1.cxx')
   TargetAdd('p3pnmimage_composite2.obj', opts=OPTS, input='p3pnmimage_composite2.cxx')
+
+  OPTS=['DIR:panda/src/pnmimage', 'ZLIB']
   IGATEFILES=GetDirectoryContents('panda/src/pnmimage', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pnmimage.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pnmimage.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pnmimage', 'SRCDIR:panda/src/pnmimage'])
@@ -3175,6 +3207,8 @@ if (not RUNTIME):
 if (not RUNTIME):
   OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'BUILDING:PANDA']
   TargetAdd('p3nativenet_composite1.obj', opts=OPTS, input='p3nativenet_composite1.cxx')
+
+  OPTS=['DIR:panda/src/nativenet', 'OPENSSL']
   IGATEFILES=GetDirectoryContents('panda/src/nativenet', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3nativenet.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3nativenet.in', opts=['IMOD:panda3d.core', 'ILIB:libp3nativenet', 'SRCDIR:panda/src/nativenet'])
@@ -3188,6 +3222,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/net', 'BUILDING:PANDA']
   TargetAdd('p3net_composite1.obj', opts=OPTS, input='p3net_composite1.cxx')
   TargetAdd('p3net_composite2.obj', opts=OPTS, input='p3net_composite2.cxx')
+
+  OPTS=['DIR:panda/src/net']
   IGATEFILES=GetDirectoryContents('panda/src/net', ["*.h", "*_composite*.cxx"])
   IGATEFILES.remove("datagram_ui.h")
   TargetAdd('libp3net.in', opts=OPTS, input=IGATEFILES)
@@ -3202,6 +3238,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/pstatclient', 'BUILDING:PANDA']
   TargetAdd('p3pstatclient_composite1.obj', opts=OPTS, input='p3pstatclient_composite1.cxx')
   TargetAdd('p3pstatclient_composite2.obj', opts=OPTS, input='p3pstatclient_composite2.cxx')
+
+  OPTS=['DIR:panda/src/pstatclient']
   IGATEFILES=GetDirectoryContents('panda/src/pstatclient', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pstatclient.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pstatclient.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pstatclient', 'SRCDIR:panda/src/pstatclient'])
@@ -3212,25 +3250,28 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/gobj', 'BUILDING:PANDA',  'NVIDIACG', 'ZLIB', 'SQUISH', "BIGOBJ"]
+  OPTS=['DIR:panda/src/gobj', 'BUILDING:PANDA',  'NVIDIACG', 'ZLIB', 'SQUISH']
   TargetAdd('p3gobj_composite1.obj', opts=OPTS, input='p3gobj_composite1.cxx')
   TargetAdd('p3gobj_composite2.obj', opts=OPTS, input='p3gobj_composite2.cxx')
+
+  OPTS=['DIR:panda/src/gobj', 'NVIDIACG', 'ZLIB', 'SQUISH']
   IGATEFILES=GetDirectoryContents('panda/src/gobj', ["*.h", "*_composite*.cxx"])
   if ("cgfx_states.h" in IGATEFILES): IGATEFILES.remove("cgfx_states.h")
   TargetAdd('libp3gobj.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3gobj.in', opts=['IMOD:panda3d.core', 'ILIB:libp3gobj', 'SRCDIR:panda/src/gobj'])
   TargetAdd('libp3gobj_igate.obj', input='libp3gobj.in', opts=["DEPENDENCYONLY"])
-  TargetAdd('p3gobj_geomVertexArrayData_ext.obj', opts=OPTS, input='geomVertexArrayData_ext.cxx')
-  TargetAdd('p3gobj_internalName_ext.obj', opts=OPTS, input='internalName_ext.cxx')
+  TargetAdd('p3gobj_ext_composite.obj', opts=OPTS, input='p3gobj_ext_composite.cxx')
 
 #
 # DIRECTORY: panda/src/pgraphnodes/
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/pgraphnodes', 'BUILDING:PANDA', "BIGOBJ"]
+  OPTS=['DIR:panda/src/pgraphnodes', 'BUILDING:PANDA']
   TargetAdd('p3pgraphnodes_composite1.obj', opts=OPTS, input='p3pgraphnodes_composite1.cxx')
   TargetAdd('p3pgraphnodes_composite2.obj', opts=OPTS, input='p3pgraphnodes_composite2.cxx')
+
+  OPTS=['DIR:panda/src/pgraphnodes']
   IGATEFILES=GetDirectoryContents('panda/src/pgraphnodes', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pgraphnodes.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pgraphnodes.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgraphnodes', 'SRCDIR:panda/src/pgraphnodes'])
@@ -3241,12 +3282,14 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/pgraph', 'BUILDING:PANDA','BIGOBJ']
+  OPTS=['DIR:panda/src/pgraph', 'BUILDING:PANDA']
   TargetAdd('p3pgraph_nodePath.obj', opts=OPTS, input='nodePath.cxx')
   TargetAdd('p3pgraph_composite1.obj', opts=OPTS, input='p3pgraph_composite1.cxx')
   TargetAdd('p3pgraph_composite2.obj', opts=OPTS, input='p3pgraph_composite2.cxx')
   TargetAdd('p3pgraph_composite3.obj', opts=OPTS, input='p3pgraph_composite3.cxx')
   TargetAdd('p3pgraph_composite4.obj', opts=OPTS, input='p3pgraph_composite4.cxx')
+
+  OPTS=['DIR:panda/src/pgraph']
   IGATEFILES=GetDirectoryContents('panda/src/pgraph', ["*.h", "nodePath.cxx", "*_composite*.cxx"])
   TargetAdd('libp3pgraph.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgraph', 'SRCDIR:panda/src/pgraph'])
@@ -3258,9 +3301,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/cull', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/cull', 'BUILDING:PANDA']
   TargetAdd('p3cull_composite1.obj', opts=OPTS, input='p3cull_composite1.cxx')
   TargetAdd('p3cull_composite2.obj', opts=OPTS, input='p3cull_composite2.cxx')
+
+  OPTS=['DIR:panda/src/cull']
   IGATEFILES=GetDirectoryContents('panda/src/cull', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3cull.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull'])
@@ -3271,9 +3316,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/chan', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/chan', 'BUILDING:PANDA']
   TargetAdd('p3chan_composite1.obj', opts=OPTS, input='p3chan_composite1.cxx')
   TargetAdd('p3chan_composite2.obj', opts=OPTS, input='p3chan_composite2.cxx')
+
+  OPTS=['DIR:panda/src/chan']
   IGATEFILES=GetDirectoryContents('panda/src/chan', ["*.h", "*_composite*.cxx"])
   IGATEFILES.remove('movingPart.h')
   IGATEFILES.remove('animChannelFixed.h')
@@ -3286,9 +3333,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/char', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/char', 'BUILDING:PANDA']
   TargetAdd('p3char_composite1.obj', opts=OPTS, input='p3char_composite1.cxx')
   TargetAdd('p3char_composite2.obj', opts=OPTS, input='p3char_composite2.cxx')
+
+  OPTS=['DIR:panda/src/char']
   IGATEFILES=GetDirectoryContents('panda/src/char', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3char.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3char.in', opts=['IMOD:panda3d.core', 'ILIB:libp3char', 'SRCDIR:panda/src/char'])
@@ -3302,6 +3351,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/dgraph', 'BUILDING:PANDA']
   TargetAdd('p3dgraph_composite1.obj', opts=OPTS, input='p3dgraph_composite1.cxx')
   TargetAdd('p3dgraph_composite2.obj', opts=OPTS, input='p3dgraph_composite2.cxx')
+
+  OPTS=['DIR:panda/src/dgraph']
   IGATEFILES=GetDirectoryContents('panda/src/dgraph', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3dgraph.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph'])
@@ -3312,9 +3363,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/display', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/display', 'BUILDING:PANDA']
   TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx')
   TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx')
+
+  OPTS=['DIR:panda/src/display']
   IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"])
   IGATEFILES.remove("renderBuffer.h")
   TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES)
@@ -3322,6 +3375,7 @@ if (not RUNTIME):
   TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"])
   TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx')
   TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx')
+  TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx')
 
   if RTDIST and GetTarget() == 'darwin':
     OPTS=['DIR:panda/src/display']
@@ -3333,9 +3387,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/device', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/device', 'BUILDING:PANDA']
   TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx')
   TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx')
+
+  OPTS=['DIR:panda/src/device']
   IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device'])
@@ -3348,6 +3404,8 @@ if (not RUNTIME):
 if (PkgSkip("FREETYPE")==0 and not RUNTIME):
   OPTS=['DIR:panda/src/pnmtext', 'BUILDING:PANDA',  'FREETYPE']
   TargetAdd('p3pnmtext_composite1.obj', opts=OPTS, input='p3pnmtext_composite1.cxx')
+
+  OPTS=['DIR:panda/src/pnmtext', 'FREETYPE']
   IGATEFILES=GetDirectoryContents('panda/src/pnmtext', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pnmtext.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pnmtext.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pnmtext', 'SRCDIR:panda/src/pnmtext'])
@@ -3358,9 +3416,11 @@ if (PkgSkip("FREETYPE")==0 and not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/text', 'BUILDING:PANDA', 'ZLIB',  'FREETYPE', 'BIGOBJ']
+  OPTS=['DIR:panda/src/text', 'BUILDING:PANDA', 'ZLIB',  'FREETYPE']
   TargetAdd('p3text_composite1.obj', opts=OPTS, input='p3text_composite1.cxx')
   TargetAdd('p3text_composite2.obj', opts=OPTS, input='p3text_composite2.cxx')
+
+  OPTS=['DIR:panda/src/text', 'ZLIB', 'FREETYPE']
   IGATEFILES=GetDirectoryContents('panda/src/text', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3text.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3text.in', opts=['IMOD:panda3d.core', 'ILIB:libp3text', 'SRCDIR:panda/src/text'])
@@ -3373,6 +3433,8 @@ if (not RUNTIME):
 if (not RUNTIME):
   OPTS=['DIR:panda/src/movies', 'BUILDING:PANDA', 'VORBIS']
   TargetAdd('p3movies_composite1.obj', opts=OPTS, input='p3movies_composite1.cxx')
+
+  OPTS=['DIR:panda/src/movies', 'VORBIS']
   IGATEFILES=GetDirectoryContents('panda/src/movies', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3movies.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3movies.in', opts=['IMOD:panda3d.core', 'ILIB:libp3movies', 'SRCDIR:panda/src/movies'])
@@ -3383,10 +3445,12 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/grutil', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/grutil', 'BUILDING:PANDA']
   TargetAdd('p3grutil_multitexReducer.obj', opts=OPTS, input='multitexReducer.cxx')
   TargetAdd('p3grutil_composite1.obj', opts=OPTS, input='p3grutil_composite1.cxx')
   TargetAdd('p3grutil_composite2.obj', opts=OPTS, input='p3grutil_composite2.cxx')
+
+  OPTS=['DIR:panda/src/grutil']
   IGATEFILES=GetDirectoryContents('panda/src/grutil', ["*.h", "*_composite*.cxx"])
   if 'convexHull.h' in IGATEFILES: IGATEFILES.remove('convexHull.h')
   TargetAdd('libp3grutil.in', opts=OPTS, input=IGATEFILES)
@@ -3398,9 +3462,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/tform', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/tform', 'BUILDING:PANDA']
   TargetAdd('p3tform_composite1.obj', opts=OPTS, input='p3tform_composite1.cxx')
   TargetAdd('p3tform_composite2.obj', opts=OPTS, input='p3tform_composite2.cxx')
+
+  OPTS=['DIR:panda/src/tform']
   IGATEFILES=GetDirectoryContents('panda/src/tform', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3tform.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3tform.in', opts=['IMOD:panda3d.core', 'ILIB:libp3tform', 'SRCDIR:panda/src/tform'])
@@ -3411,9 +3477,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/collide', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/collide', 'BUILDING:PANDA']
   TargetAdd('p3collide_composite1.obj', opts=OPTS, input='p3collide_composite1.cxx')
   TargetAdd('p3collide_composite2.obj', opts=OPTS, input='p3collide_composite2.cxx')
+
+  OPTS=['DIR:panda/src/collide']
   IGATEFILES=GetDirectoryContents('panda/src/collide', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3collide.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3collide.in', opts=['IMOD:panda3d.core', 'ILIB:libp3collide', 'SRCDIR:panda/src/collide'])
@@ -3424,9 +3492,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/parametrics', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/parametrics', 'BUILDING:PANDA']
   TargetAdd('p3parametrics_composite1.obj', opts=OPTS, input='p3parametrics_composite1.cxx')
   TargetAdd('p3parametrics_composite2.obj', opts=OPTS, input='p3parametrics_composite2.cxx')
+
+  OPTS=['DIR:panda/src/parametrics']
   IGATEFILES=GetDirectoryContents('panda/src/parametrics', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3parametrics.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3parametrics.in', opts=['IMOD:panda3d.core', 'ILIB:libp3parametrics', 'SRCDIR:panda/src/parametrics'])
@@ -3437,9 +3507,11 @@ if (not RUNTIME):
 #
 
 if (not RUNTIME):
-  OPTS=['DIR:panda/src/pgui', 'BUILDING:PANDA', 'BIGOBJ']
+  OPTS=['DIR:panda/src/pgui', 'BUILDING:PANDA']
   TargetAdd('p3pgui_composite1.obj', opts=OPTS, input='p3pgui_composite1.cxx')
   TargetAdd('p3pgui_composite2.obj', opts=OPTS, input='p3pgui_composite2.cxx')
+
+  OPTS=['DIR:panda/src/pgui']
   IGATEFILES=GetDirectoryContents('panda/src/pgui', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3pgui.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3pgui.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgui', 'SRCDIR:panda/src/pgui'])
@@ -3462,6 +3534,8 @@ if (not RUNTIME):
   OPTS=['DIR:panda/src/recorder', 'BUILDING:PANDA']
   TargetAdd('p3recorder_composite1.obj', opts=OPTS, input='p3recorder_composite1.cxx')
   TargetAdd('p3recorder_composite2.obj', opts=OPTS, input='p3recorder_composite2.cxx')
+
+  OPTS=['DIR:panda/src/recorder']
   IGATEFILES=GetDirectoryContents('panda/src/recorder', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3recorder.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3recorder.in', opts=['IMOD:panda3d.core', 'ILIB:libp3recorder', 'SRCDIR:panda/src/recorder'])
@@ -3481,6 +3555,8 @@ if (RUNTIME or RTDIST):
 if (not RUNTIME):
   OPTS=['DIR:panda/src/dxml', 'BUILDING:PANDA', 'TINYXML']
   TargetAdd('p3dxml_composite1.obj', opts=OPTS, input='p3dxml_composite1.cxx')
+
+  OPTS=['DIR:panda/src/dxml', 'TINYXML']
   IGATEFILES=GetDirectoryContents('panda/src/dxml', ["*.h", "p3dxml_composite1.cxx"])
   TargetAdd('libp3dxml.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3dxml.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dxml', 'SRCDIR:panda/src/dxml'])
@@ -3500,108 +3576,71 @@ if (not RUNTIME):
   TargetAdd('libpanda.dll', input='panda_panda.obj')
   TargetAdd('libpanda.dll', input='p3recorder_composite1.obj')
   TargetAdd('libpanda.dll', input='p3recorder_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3recorder_igate.obj')
   TargetAdd('libpanda.dll', input='p3pgraphnodes_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pgraphnodes_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3pgraphnodes_igate.obj')
   TargetAdd('libpanda.dll', input='p3pgraph_nodePath.obj')
   TargetAdd('libpanda.dll', input='p3pgraph_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pgraph_composite2.obj')
   TargetAdd('libpanda.dll', input='p3pgraph_composite3.obj')
   TargetAdd('libpanda.dll', input='p3pgraph_composite4.obj')
-  TargetAdd('libpanda.dll', input='libp3pgraph_igate.obj')
   TargetAdd('libpanda.dll', input='p3cull_composite1.obj')
   TargetAdd('libpanda.dll', input='p3cull_composite2.obj')
   TargetAdd('libpanda.dll', input='p3movies_composite1.obj')
-  TargetAdd('libpanda.dll', input='libp3movies_igate.obj')
   TargetAdd('libpanda.dll', input='p3grutil_multitexReducer.obj')
   TargetAdd('libpanda.dll', input='p3grutil_composite1.obj')
   TargetAdd('libpanda.dll', input='p3grutil_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3grutil_igate.obj')
   TargetAdd('libpanda.dll', input='p3chan_composite1.obj')
   TargetAdd('libpanda.dll', input='p3chan_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3chan_igate.obj')
   TargetAdd('libpanda.dll', input='p3pstatclient_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pstatclient_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3pstatclient_igate.obj')
   TargetAdd('libpanda.dll', input='p3char_composite1.obj')
   TargetAdd('libpanda.dll', input='p3char_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3char_igate.obj')
   TargetAdd('libpanda.dll', input='p3collide_composite1.obj')
   TargetAdd('libpanda.dll', input='p3collide_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3collide_igate.obj')
   TargetAdd('libpanda.dll', input='p3device_composite1.obj')
   TargetAdd('libpanda.dll', input='p3device_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3device_igate.obj')
   TargetAdd('libpanda.dll', input='p3dgraph_composite1.obj')
   TargetAdd('libpanda.dll', input='p3dgraph_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3dgraph_igate.obj')
   TargetAdd('libpanda.dll', input='p3display_composite1.obj')
   TargetAdd('libpanda.dll', input='p3display_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3display_igate.obj')
   TargetAdd('libpanda.dll', input='p3pipeline_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pipeline_composite2.obj')
   TargetAdd('libpanda.dll', input='p3pipeline_contextSwitch.obj')
-  TargetAdd('libpanda.dll', input='libp3pipeline_igate.obj')
   TargetAdd('libpanda.dll', input='p3event_composite1.obj')
   TargetAdd('libpanda.dll', input='p3event_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3event_igate.obj')
   TargetAdd('libpanda.dll', input='p3gobj_composite1.obj')
   TargetAdd('libpanda.dll', input='p3gobj_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3gobj_igate.obj')
   TargetAdd('libpanda.dll', input='p3gsgbase_composite1.obj')
-  TargetAdd('libpanda.dll', input='libp3gsgbase_igate.obj')
   TargetAdd('libpanda.dll', input='p3linmath_composite1.obj')
   TargetAdd('libpanda.dll', input='p3linmath_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3linmath_igate.obj')
   TargetAdd('libpanda.dll', input='p3mathutil_composite1.obj')
   TargetAdd('libpanda.dll', input='p3mathutil_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3mathutil_igate.obj')
   TargetAdd('libpanda.dll', input='p3parametrics_composite1.obj')
   TargetAdd('libpanda.dll', input='p3parametrics_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3parametrics_igate.obj')
   TargetAdd('libpanda.dll', input='p3pnmimagetypes_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pnmimagetypes_composite2.obj')
   TargetAdd('libpanda.dll', input='p3pnmimage_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pnmimage_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3pnmimage_igate.obj')
   TargetAdd('libpanda.dll', input='p3text_composite1.obj')
   TargetAdd('libpanda.dll', input='p3text_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3text_igate.obj')
   TargetAdd('libpanda.dll', input='p3tform_composite1.obj')
   TargetAdd('libpanda.dll', input='p3tform_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3tform_igate.obj')
   TargetAdd('libpanda.dll', input='p3putil_composite1.obj')
   TargetAdd('libpanda.dll', input='p3putil_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3putil_igate.obj')
   TargetAdd('libpanda.dll', input='p3audio_composite1.obj')
-  TargetAdd('libpanda.dll', input='libp3audio_igate.obj')
   TargetAdd('libpanda.dll', input='p3pgui_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pgui_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3pgui_igate.obj')
   TargetAdd('libpanda.dll', input='p3net_composite1.obj')
   TargetAdd('libpanda.dll', input='p3net_composite2.obj')
-  TargetAdd('libpanda.dll', input='libp3net_igate.obj')
   TargetAdd('libpanda.dll', input='p3nativenet_composite1.obj')
-  TargetAdd('libpanda.dll', input='libp3nativenet_igate.obj')
   TargetAdd('libpanda.dll', input='p3pandabase_pandabase.obj')
   TargetAdd('libpanda.dll', input='libpandaexpress.dll')
   TargetAdd('libpanda.dll', input='p3dxml_composite1.obj')
-  TargetAdd('libpanda.dll', input='libp3dxml_igate.obj')
   TargetAdd('libpanda.dll', input='libp3dtoolconfig.dll')
   TargetAdd('libpanda.dll', input='libp3dtool.dll')
 
-  TargetAdd('libpanda.dll', input='p3putil_typedWritable_ext.obj')
-  TargetAdd('libpanda.dll', input='p3pnmimage_pfmFile_ext.obj')
-  TargetAdd('libpanda.dll', input='p3gobj_geomVertexArrayData_ext.obj')
-  TargetAdd('libpanda.dll', input='p3gobj_internalName_ext.obj')
-  TargetAdd('libpanda.dll', input='p3pgraph_ext_composite.obj')
-  TargetAdd('libpanda.dll', input='p3display_graphicsStateGuardian_ext.obj')
-  TargetAdd('libpanda.dll', input='p3display_graphicsWindow_ext.obj')
-
   if PkgSkip("FREETYPE")==0:
     TargetAdd('libpanda.dll', input="p3pnmtext_composite1.obj")
-    TargetAdd('libpanda.dll', input="libp3pnmtext_igate.obj")
 
   TargetAdd('libpanda.dll', dep='dtool_have_freetype.dat')
   TargetAdd('libpanda.dll', opts=OPTS)
@@ -3644,9 +3683,56 @@ if (not RUNTIME):
 
   TargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core'])
 
+  OPTS=['WINSOCK2']
+  TargetAdd('core.pyd', input='libp3downloader_igate.obj')
+  TargetAdd('core.pyd', input='p3express_ext_composite.obj')
+  TargetAdd('core.pyd', input='libp3express_igate.obj')
+
+  TargetAdd('core.pyd', input='libp3recorder_igate.obj')
+  TargetAdd('core.pyd', input='libp3pgraphnodes_igate.obj')
+  TargetAdd('core.pyd', input='libp3pgraph_igate.obj')
+  TargetAdd('core.pyd', input='libp3movies_igate.obj')
+  TargetAdd('core.pyd', input='libp3grutil_igate.obj')
+  TargetAdd('core.pyd', input='libp3chan_igate.obj')
+  TargetAdd('core.pyd', input='libp3pstatclient_igate.obj')
+  TargetAdd('core.pyd', input='libp3char_igate.obj')
+  TargetAdd('core.pyd', input='libp3collide_igate.obj')
+  TargetAdd('core.pyd', input='libp3device_igate.obj')
+  TargetAdd('core.pyd', input='libp3dgraph_igate.obj')
+  TargetAdd('core.pyd', input='libp3display_igate.obj')
+  TargetAdd('core.pyd', input='libp3pipeline_igate.obj')
+  TargetAdd('core.pyd', input='libp3event_igate.obj')
+  TargetAdd('core.pyd', input='libp3gobj_igate.obj')
+  TargetAdd('core.pyd', input='libp3gsgbase_igate.obj')
+  TargetAdd('core.pyd', input='libp3linmath_igate.obj')
+  TargetAdd('core.pyd', input='libp3mathutil_igate.obj')
+  TargetAdd('core.pyd', input='libp3parametrics_igate.obj')
+  TargetAdd('core.pyd', input='libp3pnmimage_igate.obj')
+  TargetAdd('core.pyd', input='libp3text_igate.obj')
+  TargetAdd('core.pyd', input='libp3tform_igate.obj')
+  TargetAdd('core.pyd', input='libp3putil_igate.obj')
+  TargetAdd('core.pyd', input='libp3audio_igate.obj')
+  TargetAdd('core.pyd', input='libp3pgui_igate.obj')
+  TargetAdd('core.pyd', input='libp3net_igate.obj')
+  TargetAdd('core.pyd', input='libp3nativenet_igate.obj')
+  TargetAdd('core.pyd', input='libp3dxml_igate.obj')
+
+  if PkgSkip("FREETYPE")==0:
+    TargetAdd('core.pyd', input="libp3pnmtext_igate.obj")
+
+  TargetAdd('core.pyd', input='p3putil_typedWritable_ext.obj')
+  TargetAdd('core.pyd', input='p3putil_pythonCallbackObject.obj')
+  TargetAdd('core.pyd', input='p3pnmimage_pfmFile_ext.obj')
+  TargetAdd('core.pyd', input='p3event_pythonTask.obj')
+  TargetAdd('core.pyd', input='p3gobj_ext_composite.obj')
+  TargetAdd('core.pyd', input='p3pgraph_ext_composite.obj')
+  TargetAdd('core.pyd', input='p3display_graphicsStateGuardian_ext.obj')
+  TargetAdd('core.pyd', input='p3display_graphicsWindow_ext.obj')
+  TargetAdd('core.pyd', input='p3display_pythonGraphicsWindowProc.obj')
+
   TargetAdd('core.pyd', input='core_module.obj')
   TargetAdd('core.pyd', input=COMMON_PANDA_LIBS)
-  TargetAdd('core.pyd', opts=['PYTHON'])
+  TargetAdd('core.pyd', opts=OPTS)
 
 #
 # DIRECTORY: panda/src/vision/
@@ -4527,6 +4613,8 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx')
   TargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx')
   TargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx')
+
+  OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA']
   IGATEFILES=GetDirectoryContents('direct/src/dcparser', ["*.h", "*_composite*.cxx"])
   if "dcParser.h" in IGATEFILES: IGATEFILES.remove("dcParser.h")
   if "dcmsgtypes.h" in IGATEFILES: IGATEFILES.remove('dcmsgtypes.h')
@@ -4541,6 +4629,8 @@ if (PkgSkip("DIRECT")==0):
 if (PkgSkip("DIRECT")==0):
   OPTS=['DIR:direct/src/deadrec', 'BUILDING:DIRECT']
   TargetAdd('p3deadrec_composite1.obj', opts=OPTS, input='p3deadrec_composite1.cxx')
+
+  OPTS=['DIR:direct/src/deadrec']
   IGATEFILES=GetDirectoryContents('direct/src/deadrec', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3deadrec.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3deadrec.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3deadrec', 'SRCDIR:direct/src/deadrec'])
@@ -4555,6 +4645,8 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx')
   TargetAdd('p3distributed_cConnectionRepository.obj', opts=OPTS, input='cConnectionRepository.cxx')
   TargetAdd('p3distributed_cDistributedSmoothNodeBase.obj', opts=OPTS, input='cDistributedSmoothNodeBase.cxx')
+
+  OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL']
   IGATEFILES=GetDirectoryContents('direct/src/distributed', ["*.h", "*.cxx"])
   TargetAdd('libp3distributed.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3distributed.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3distributed', 'SRCDIR:direct/src/distributed'])
@@ -4567,6 +4659,8 @@ if (PkgSkip("DIRECT")==0):
 if (PkgSkip("DIRECT")==0):
   OPTS=['DIR:direct/src/interval', 'BUILDING:DIRECT']
   TargetAdd('p3interval_composite1.obj', opts=OPTS, input='p3interval_composite1.cxx')
+
+  OPTS=['DIR:direct/src/interval']
   IGATEFILES=GetDirectoryContents('direct/src/interval', ["*.h", "*_composite*.cxx"])
   TargetAdd('libp3interval.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3interval.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3interval', 'SRCDIR:direct/src/interval'])
@@ -4581,6 +4675,8 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('p3showbase_showBase.obj', opts=OPTS, input='showBase.cxx')
   if GetTarget() == 'darwin':
     TargetAdd('p3showbase_showBase_assist.obj', opts=OPTS, input='showBase_assist.mm')
+
+  OPTS=['DIR:direct/src/showbase']
   IGATEFILES=GetDirectoryContents('direct/src/showbase', ["*.h", "showBase.cxx"])
   TargetAdd('libp3showbase.in', opts=OPTS, input=IGATEFILES)
   TargetAdd('libp3showbase.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3showbase', 'SRCDIR:direct/src/showbase'])
@@ -4600,19 +4696,14 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('libp3direct.dll', input='p3dcparser_composite2.obj')
   TargetAdd('libp3direct.dll', input='p3dcparser_dcParser.obj')
   TargetAdd('libp3direct.dll', input='p3dcparser_dcLexer.obj')
-  TargetAdd('libp3direct.dll', input='libp3dcparser_igate.obj')
   TargetAdd('libp3direct.dll', input='p3showbase_showBase.obj')
   if GetTarget() == 'darwin':
     TargetAdd('libp3direct.dll', input='p3showbase_showBase_assist.obj')
-  TargetAdd('libp3direct.dll', input='libp3showbase_igate.obj')
   TargetAdd('libp3direct.dll', input='p3deadrec_composite1.obj')
-  TargetAdd('libp3direct.dll', input='libp3deadrec_igate.obj')
   TargetAdd('libp3direct.dll', input='p3interval_composite1.obj')
-  TargetAdd('libp3direct.dll', input='libp3interval_igate.obj')
   TargetAdd('libp3direct.dll', input='p3distributed_config_distributed.obj')
   TargetAdd('libp3direct.dll', input='p3distributed_cConnectionRepository.obj')
   TargetAdd('libp3direct.dll', input='p3distributed_cDistributedSmoothNodeBase.obj')
-  TargetAdd('libp3direct.dll', input='libp3distributed_igate.obj')
   TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3direct.dll', opts=['ADVAPI',  'OPENSSL', 'WINUSER', 'WINGDI'])
 
@@ -4625,6 +4716,12 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('direct_module.obj', opts=OPTS)
   TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct'])
 
+  TargetAdd('direct.pyd', input='libp3dcparser_igate.obj')
+  TargetAdd('direct.pyd', input='libp3showbase_igate.obj')
+  TargetAdd('direct.pyd', input='libp3deadrec_igate.obj')
+  TargetAdd('direct.pyd', input='libp3interval_igate.obj')
+  TargetAdd('direct.pyd', input='libp3distributed_igate.obj')
+
   TargetAdd('direct.pyd', input='direct_module.obj')
   TargetAdd('direct.pyd', input='libp3direct.dll')
   TargetAdd('direct.pyd', input='core.pyd')
@@ -5246,9 +5343,8 @@ if (PkgSkip("PANDATOOL")==0):
 
 if (PkgSkip("PANDATOOL")==0):
   OPTS=['DIR:pandatool/src/flt', 'ZLIB']
-  TargetAdd('p3flt_fltVectorRecord.obj', opts=OPTS, input='fltVectorRecord.cxx')
   TargetAdd('p3flt_composite1.obj', opts=OPTS, input='p3flt_composite1.cxx')
-  TargetAdd('libp3flt.lib', input=['p3flt_fltVectorRecord.obj', 'p3flt_composite1.obj'])
+  TargetAdd('libp3flt.lib', input=['p3flt_composite1.obj'])
 
 #
 # DIRECTORY: pandatool/src/fltegg/

+ 46 - 19
panda/src/collide/collisionBox.cxx

@@ -29,7 +29,7 @@
 #include "cmath.h"
 #include "mathNumbers.h"
 #include "geom.h"
-#include "geomTrifans.h"
+#include "geomTriangles.h"
 #include "geomVertexWriter.h"
 #include "config_mathutil.h"
 #include "dcast.h"
@@ -80,7 +80,7 @@ setup_box(){
 //     Function: CollisionBox::setup_points
 //       Access: Private
 //  Description: Computes the plane and 2d projection of points that
-//               make up this side          
+//               make up this side.
 ////////////////////////////////////////////////////////////////////
 void CollisionBox::
 setup_points(const LPoint3 *begin, const LPoint3 *end, int plane) {
@@ -552,7 +552,7 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   PN_stdfloat near_t = 0.0;
   bool intersect;
   LPlane plane;
-  LPlane near_plane; 
+  LPlane near_plane;
 
   //Returns the details about the first plane of the box that the
   //segment intersects.
@@ -589,7 +589,6 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
     }
     ++j;
   }
-   
 
   if(!intersect) {
     //No intersection with ANY of the box's planes has been detected
@@ -645,22 +644,50 @@ fill_viz_geom() {
   PT(GeomVertexData) vdata = new GeomVertexData
     ("collision", GeomVertexFormat::get_v3(),
      Geom::UH_static);
-  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
-  
-  for(int i = 0; i < 6; i++) {
-    for(int j = 0; j < 4; j++)
-      vertex.add_data3(get_point(plane_def[i][j]));
 
-    PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static);
-    body->add_consecutive_vertices(i*4, 4);
-    body->close_primitive();
+  vdata->unclean_set_num_rows(8);
 
-    PT(Geom) geom = new Geom(vdata);
-    geom->add_primitive(body);
+  {
+    GeomVertexWriter vertex(vdata, InternalName::get_vertex());
+    vertex.set_data3(_min[0], _min[1], _min[2]);
+    vertex.set_data3(_min[0], _max[1], _min[2]);
+    vertex.set_data3(_max[0], _max[1], _min[2]);
+    vertex.set_data3(_max[0], _min[1], _min[2]);
 
-    _viz_geom->add_geom(geom, get_solid_viz_state());
-    _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
+    vertex.set_data3(_min[0], _min[1], _max[2]);
+    vertex.set_data3(_min[0], _max[1], _max[2]);
+    vertex.set_data3(_max[0], _max[1], _max[2]);
+    vertex.set_data3(_max[0], _min[1], _max[2]);
   }
+
+  PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
+
+  // Bottom
+  tris->add_vertices(0, 1, 2);
+  tris->add_vertices(2, 3, 0);
+
+  // Top
+  tris->add_vertices(4, 7, 6);
+  tris->add_vertices(6, 5, 4);
+
+  // Sides
+  tris->add_vertices(0, 4, 1);
+  tris->add_vertices(1, 4, 5);
+
+  tris->add_vertices(1, 5, 2);
+  tris->add_vertices(2, 5, 6);
+
+  tris->add_vertices(2, 6, 3);
+  tris->add_vertices(3, 6, 7);
+
+  tris->add_vertices(3, 7, 0);
+  tris->add_vertices(0, 7, 4);
+
+  PT(Geom) geom = new Geom(vdata);
+  geom->add_primitive(tris);
+
+  _viz_geom->add_geom(geom, get_solid_viz_state());
+  _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -675,7 +702,7 @@ fill_viz_geom() {
 //               planes), or false otherwise.
 ////////////////////////////////////////////////////////////////////
 bool CollisionBox::
-apply_clip_plane(CollisionBox::Points &new_points, 
+apply_clip_plane(CollisionBox::Points &new_points,
                  const ClipPlaneAttrib *cpa,
                  const TransformState *net_transform, int plane_no) const {
   bool all_in = true;
@@ -687,9 +714,9 @@ apply_clip_plane(CollisionBox::Points &new_points,
     NodePath plane_path = cpa->get_on_plane(i);
     PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
     if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) {
-      CPT(TransformState) new_transform = 
+      CPT(TransformState) new_transform =
         net_transform->invert_compose(plane_path.get_net_transform());
-      
+
       LPlane plane = plane_node->get_plane() * new_transform->get_mat();
       if (first_plane) {
         first_plane = false;

+ 1 - 1
panda/src/display/Sources.pp

@@ -14,6 +14,7 @@
     standardMunger.I standardMunger.h \
     config_display.h \
     $[if $[HAVE_PYTHON], pythonGraphicsWindowProc.h] \
+    $[if $[HAVE_PYTHON], pythonGraphicsWindowProc.cxx] \
     callbackGraphicsWindow.I callbackGraphicsWindow.h \
     drawableRegion.I drawableRegion.h \
     displayRegion.I displayRegion.h  \
@@ -54,7 +55,6 @@
  #define INCLUDED_SOURCES  \
     standardMunger.cxx \
     config_display.cxx \
-    $[if $[HAVE_PYTHON], pythonGraphicsWindowProc.cxx] \
     callbackGraphicsWindow.cxx \
     drawableRegion.cxx \
     displayRegion.cxx \

+ 4 - 5
panda/src/display/callbackGraphicsWindow.h

@@ -40,7 +40,7 @@ protected:
 PUBLISHED:
   virtual ~CallbackGraphicsWindow();
 
-  class WindowCallbackData : public CallbackData {
+  class EXPCL_PANDA_DISPLAY WindowCallbackData : public CallbackData {
   public:
     INLINE WindowCallbackData(CallbackGraphicsWindow *window);
 
@@ -68,8 +68,7 @@ PUBLISHED:
     static TypeHandle _type_handle;
   };
 
-
-  class EventsCallbackData : public WindowCallbackData {
+  class EXPCL_PANDA_DISPLAY EventsCallbackData : public WindowCallbackData {
   public:
     INLINE EventsCallbackData(CallbackGraphicsWindow *window);
 
@@ -94,7 +93,7 @@ PUBLISHED:
     static TypeHandle _type_handle;
   };
 
-  class PropertiesCallbackData : public WindowCallbackData {
+  class EXPCL_PANDA_DISPLAY PropertiesCallbackData : public WindowCallbackData {
   public:
     INLINE PropertiesCallbackData(CallbackGraphicsWindow *window, WindowProperties &properties);
 
@@ -131,7 +130,7 @@ PUBLISHED:
     RCT_end_flip,
   };
 
-  class RenderCallbackData : public WindowCallbackData {
+  class EXPCL_PANDA_DISPLAY RenderCallbackData : public WindowCallbackData {
   public:
     INLINE RenderCallbackData(CallbackGraphicsWindow *window, RenderCallbackType callback_type, FrameMode frame_mode);
 

+ 4 - 4
panda/src/display/displayRegion.cxx

@@ -636,7 +636,7 @@ void DisplayRegion::
 compute_pixels() {
   if (_window != (GraphicsOutput *)NULL) {
     CDWriter cdata(_cycler, false);
-    for (int i = 0; i < cdata->_regions.size(); ++i) {
+    for (size_t i = 0; i < cdata->_regions.size(); ++i) {
       do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), 
                         cdata);
     }
@@ -658,7 +658,7 @@ compute_pixels_all_stages() {
   if (_window != (GraphicsOutput *)NULL) {
     OPEN_ITERATE_ALL_STAGES(_cycler) {
       CDStageWriter cdata(_cycler, pipeline_stage);
-      for (int i = 0; i < cdata->_regions.size(); ++i) {
+      for (size_t i = 0; i < cdata->_regions.size(); ++i) {
         do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), 
                           cdata);
       }
@@ -677,7 +677,7 @@ compute_pixels_all_stages() {
 void DisplayRegion::
 compute_pixels(int x_size, int y_size) {
   CDWriter cdata(_cycler, false);
-  for (int i = 0; i < cdata->_regions.size(); ++i) {
+  for (size_t i = 0; i < cdata->_regions.size(); ++i) {
     do_compute_pixels(i, x_size, y_size, cdata);
   }
 }
@@ -695,7 +695,7 @@ void DisplayRegion::
 compute_pixels_all_stages(int x_size, int y_size) {
   OPEN_ITERATE_ALL_STAGES(_cycler) {
     CDStageWriter cdata(_cycler, pipeline_stage);
-    for (int i = 0; i < cdata->_regions.size(); ++i) {
+    for (size_t i = 0; i < cdata->_regions.size(); ++i) {
       do_compute_pixels(i, x_size, y_size, cdata);
     }
   } 

+ 58 - 4
panda/src/display/graphicsStateGuardian.cxx

@@ -936,13 +936,13 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
   LVecBase3 v;
 
   if (altered & spec._dep[0]) {
-    const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0]);
+    const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index);
     if (t != &spec._cache[0]) {
       spec._cache[0] = *t;
     }
   }
   if (altered & spec._dep[1]) {
-    const LMatrix4 *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1]);
+    const LMatrix4 *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index);
     if (t != &spec._cache[1]) {
       spec._cache[1] = *t;
     }
@@ -987,8 +987,9 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
 //  Description: See fetch_specified_value
 ////////////////////////////////////////////////////////////////////
 const LMatrix4 *GraphicsStateGuardian::
-fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &t) {
-  switch(part) {
+fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
+                     LMatrix4 &t, int index) {
+  switch (part) {
   case Shader::SMO_identity: {
     return &LMatrix4::ident_mat();
   }
@@ -1223,6 +1224,25 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
     return &t;
   }
+  case Shader::SMO_apiview_clipplane_i: {
+    const ClipPlaneAttrib *cpa = DCAST(ClipPlaneAttrib, _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
+    if (index >= cpa->get_num_on_planes()) {
+      return &LMatrix4::zeros_mat();
+    }
+
+    const NodePath &plane = cpa->get_on_plane(index);
+    nassertr(!plane.is_empty(), &LMatrix4::zeros_mat());
+    const PlaneNode *plane_node;
+    DCAST_INTO_R(plane_node, plane.node(), &LMatrix4::zeros_mat());
+
+    CPT(TransformState) transform =
+      get_scene()->get_cs_world_transform()->compose(
+        plane.get_transform(_scene_setup->get_scene_root().get_parent()));
+
+    LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
+    t.set_row(3, xformed_plane);
+    return &t;
+  }
   case Shader::SMO_mat_constant_x: {
     return &_target_shader->get_shader_input_matrix(name, t);
   }
@@ -1377,6 +1397,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
     static const CPT_InternalName IN_diffuse("diffuse");
     static const CPT_InternalName IN_specular("specular");
     static const CPT_InternalName IN_position("position");
+    static const CPT_InternalName IN_halfVector("halfVector");
     static const CPT_InternalName IN_spotDirection("spotDirection");
     static const CPT_InternalName IN_spotCutoff("spotCutoff");
     static const CPT_InternalName IN_spotCosCutoff("spotCosCutoff");
@@ -1435,6 +1456,39 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
         t = LMatrix4::translate_mat(pos);
         return &t;
       }
+
+    } else if (attrib == IN_halfVector) {
+      if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+        DirectionalLight *light;
+        DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+
+        CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
+        LVector3 dir = -(light->get_direction() * transform->get_mat());
+        dir *= get_scene()->get_cs_world_transform()->get_mat();
+        dir.normalize();
+        dir += LVector3(0, 0, 1);
+        dir.normalize();
+        t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1);
+        return &t;
+      } else {
+        LightLensNode *light;
+        DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+        Lens *lens = light->get_lens();
+        nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
+
+        CPT(TransformState) transform =
+          get_scene()->get_cs_world_transform()->compose(
+            np.get_transform(_scene_setup->get_scene_root().get_parent()));
+
+        const LMatrix4 &light_mat = transform->get_mat();
+        LPoint3 pos = lens->get_nodal_point() * light_mat;
+        pos.normalize();
+        pos += LVector3(0, 0, 1);
+        pos.normalize();
+        t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1);
+        return &t;
+      }
+
     } else if (attrib == IN_spotDirection) {
       LightLensNode *light;
       DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());

+ 2 - 1
panda/src/display/graphicsStateGuardian.h

@@ -255,7 +255,8 @@ public:
   virtual void clear(DrawableRegion *clearable);
 
   const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered);
-  const LMatrix4 *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4 &t);
+  const LMatrix4 *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
+                                       LMatrix4 &t, int index);
   const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
 
   virtual void prepare_display_region(DisplayRegionPipelineReader *dr);

+ 1 - 1
panda/src/display/graphicsStateGuardian_ext.cxx

@@ -18,7 +18,7 @@
 #ifdef HAVE_PYTHON
 
 #ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject Dtool_Texture;
+extern struct Dtool_PyTypedObject Dtool_Texture;
 #endif
 
 static bool traverse_callback(TextureContext *tc, void *data) {

+ 6 - 4
panda/src/display/graphicsWindowProc.h

@@ -12,7 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
 #ifndef GRAPHICSWINDOWPROC_H
 #define GRAPHICSWINDOWPROC_H
 
@@ -25,18 +24,21 @@
 #include <windows.h>
 #endif
 
+class GraphicsWindow;
+
 ////////////////////////////////////////////////////////////////////
 //       Class : GraphicsWindowProc
 // Description : Defines an interface for storing platform-specific
 //               window processor methods.
 ////////////////////////////////////////////////////////////////////
-class GraphicsWindowProc{
+class EXPCL_PANDA_DISPLAY GraphicsWindowProc {
 public:
   GraphicsWindowProc();
 #if defined(__WIN32__) || defined(_WIN32)
-  virtual LONG wnd_proc(GraphicsWindow* graphicsWindow, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+  virtual LONG wnd_proc(GraphicsWindow* graphicsWindow, HWND hwnd,
+                        UINT msg, WPARAM wparam, LPARAM lparam);
 #endif
   //purely virtual class
 };
 
-#endif //GRAPHICSWINDOWPROC_H
+#endif  // GRAPHICSWINDOWPROC_H

+ 0 - 3
panda/src/display/p3display_composite2.cxx

@@ -4,9 +4,6 @@
 #include "graphicsWindow.cxx"
 #include "graphicsWindowProc.cxx"
 #include "graphicsWindowProcCallbackData.cxx"
-#ifdef HAVE_PYTHON
-#include "pythonGraphicsWindowProc.cxx"
-#endif
 #include "graphicsWindowInputDevice.cxx"
 #include "lru.cxx"
 #include "nativeWindowHandle.cxx"

+ 4 - 0
panda/src/display/pythonGraphicsWindowProc.cxx

@@ -15,6 +15,8 @@
 #include "pythonGraphicsWindowProc.h"
 #include "graphicsWindowProcCallbackData.h"
 
+#ifdef HAVE_PYTHON
+
 TypeHandle PythonGraphicsWindowProc::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -72,3 +74,5 @@ PyObject* PythonGraphicsWindowProc::
 get_name(){
   return _name;
 }
+
+#endif  // HAVE_PYTHON

+ 11 - 5
panda/src/display/pythonGraphicsWindowProc.h

@@ -19,25 +19,29 @@
 #include "graphicsWindowProc.h"
 #include "pythonCallbackObject.h"
 
+#ifdef HAVE_PYTHON
+
 ////////////////////////////////////////////////////////////////////
 //       Class : PythonGraphicsWindowProc
 // Description : Extends GraphicsWindowProc to provde callback functionality
 //               to a python program.
 ////////////////////////////////////////////////////////////////////
-class PythonGraphicsWindowProc: public GraphicsWindowProc, public PythonCallbackObject{
+class PythonGraphicsWindowProc: public GraphicsWindowProc,
+                                public PythonCallbackObject {
 public:
   PythonGraphicsWindowProc(PyObject *function, PyObject* name);
   virtual ~PythonGraphicsWindowProc();
   ALLOC_DELETED_CHAIN(PythonGraphicsWindowProc);
 
 #ifdef WIN32
-  virtual LONG wnd_proc(GraphicsWindow* graphicsWindow, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+  virtual LONG wnd_proc(GraphicsWindow* graphicsWindow, HWND hwnd,
+                        UINT msg, WPARAM wparam, LPARAM lparam);
 #endif
 
-  PyObject* get_name();
+  PyObject *get_name();
 
 private:
-  PyObject* _name;
+  PyObject *_name;
 
 public:
   static TypeHandle get_class_type() {
@@ -57,4 +61,6 @@ private:
   static TypeHandle _type_handle;
 };
 
-#endif //PYTHONGRAPHICSWINDOWPROC_H
+#endif  // HAVE_PYTHON
+
+#endif  // PYTHONGRAPHICSWINDOWPROC_H

+ 1 - 5
panda/src/downloader/httpAuthorization.h

@@ -35,12 +35,8 @@ class URLSpec;
 //               authorization requests in the past, which can
 //               possibly be re-used for future requests to the same
 //               server.
-//
-//               This class does not need to be exported from the DLL
-//               because it has no public interface; it is simply a
-//               helper class for HTTPChannel.
 ////////////////////////////////////////////////////////////////////
-class HTTPAuthorization : public ReferenceCount {
+class EXPCL_PANDAEXPRESS HTTPAuthorization : public ReferenceCount {
 public:
   typedef pmap<string, string> Tokens;
   typedef pmap<string, Tokens> AuthenticationSchemes;

+ 3 - 1
panda/src/dxgsg9/dxgsg9base.h

@@ -19,7 +19,9 @@
 #include "graphicsWindow.h"
 #include "pmap.h"
 
-#define WIN32_LEAN_AND_MEAN   // get rid of mfc win32 hdr stuff
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1  // get rid of mfc win32 hdr stuff
+#endif
 #ifndef STRICT
 // enable strict type checking in windows.h, see msdn
 #define STRICT

+ 4 - 4
panda/src/dxml/config_dxml.h

@@ -36,10 +36,10 @@ extern EXPCL_PANDA void init_libdxml();
 class TiXmlDocument;
 class TiXmlNode;
 BEGIN_PUBLISH
-TiXmlDocument *read_xml_stream(istream &in);
-void write_xml_stream(ostream &out, TiXmlDocument *doc);
-void print_xml(TiXmlNode *xnode);
-void print_xml_to_file(const Filename &filename, TiXmlNode *xnode);
+EXPCL_PANDA TiXmlDocument *read_xml_stream(istream &in);
+EXPCL_PANDA void write_xml_stream(ostream &out, TiXmlDocument *doc);
+EXPCL_PANDA void print_xml(TiXmlNode *xnode);
+EXPCL_PANDA void print_xml_to_file(const Filename &filename, TiXmlNode *xnode);
 END_PUBLISH
 
 #endif

+ 14 - 14
panda/src/dxml/tinyxml.h

@@ -96,7 +96,7 @@ const int TIXML_PATCH_VERSION = 1;
 /*  Internal structure for tracking location of items 
     in the XML file.
 */
-struct TiXmlCursor
+struct EXPCL_PANDA TiXmlCursor
 {
     TiXmlCursor()       { Clear(); }
     void Clear()        { row = col = -1; }
@@ -125,7 +125,7 @@ struct TiXmlCursor
 
     @sa TiXmlNode::Accept()
 */
-class TiXmlVisitor
+class EXPCL_PANDA TiXmlVisitor
 {
 public:
     virtual ~TiXmlVisitor() {}
@@ -191,7 +191,7 @@ const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
     A Decleration contains: Attributes (not on tree)
     @endverbatim
 */
-class TiXmlBase
+class EXPCL_PANDA TiXmlBase
 {
     friend class TiXmlNode;
     friend class TiXmlElement;
@@ -420,7 +420,7 @@ private:
     in a document, or stand on its own. The type of a TiXmlNode
     can be queried, and it can be cast to its more defined type.
 */
-class TiXmlNode : public TiXmlBase
+class EXPCL_PANDA TiXmlNode : public TiXmlBase
 {
     friend class TiXmlDocument;
     friend class TiXmlElement;
@@ -776,7 +776,7 @@ private:
           part of the tinyXML document object model. There are other
           suggested ways to look at this problem.
 */
-class TiXmlAttribute : public TiXmlBase
+class EXPCL_PANDA TiXmlAttribute : public TiXmlBase
 {
     friend class TiXmlAttributeSet;
 
@@ -900,7 +900,7 @@ private:
         - I like circular lists
         - it demonstrates some independence from the (typical) doubly linked list.
 */
-class TiXmlAttributeSet
+class EXPCL_PANDA TiXmlAttributeSet
 {
 public:
     TiXmlAttributeSet();
@@ -937,7 +937,7 @@ private:
     and can contain other elements, text, comments, and unknowns.
     Elements also contain an arbitrary number of attributes.
 */
-class TiXmlElement : public TiXmlNode
+class EXPCL_PANDA TiXmlElement : public TiXmlNode
 {
 public:
     /// Construct an element.
@@ -1152,7 +1152,7 @@ private:
 
 /** An XML comment.
 */
-class TiXmlComment : public TiXmlNode
+class EXPCL_PANDA TiXmlComment : public TiXmlNode
 {
 public:
     /// Constructs an empty comment.
@@ -1202,7 +1202,7 @@ private:
     you generally want to leave it alone, but you can change the output mode with 
     SetCDATA() and query it with CDATA().
 */
-class TiXmlText : public TiXmlNode
+class EXPCL_PANDA TiXmlText : public TiXmlNode
 {
     friend class TiXmlElement;
 public:
@@ -1275,7 +1275,7 @@ private:
     handled as special cases, not generic attributes, simply
     because there can only be at most 3 and they are always the same.
 */
-class TiXmlDeclaration : public TiXmlNode
+class EXPCL_PANDA TiXmlDeclaration : public TiXmlNode
 {
 public:
     /// Construct an empty declaration.
@@ -1344,7 +1344,7 @@ private:
 
     DTD tags get thrown into TiXmlUnknowns.
 */
-class TiXmlUnknown : public TiXmlNode
+class EXPCL_PANDA TiXmlUnknown : public TiXmlNode
 {
 public:
     TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )    {}
@@ -1383,7 +1383,7 @@ private:
     XML pieces. It can be saved, loaded, and printed to the screen.
     The 'value' of a document node is the xml file name.
 */
-class TiXmlDocument : public TiXmlNode
+class EXPCL_PANDA TiXmlDocument : public TiXmlNode
 {
 public:
     /// Create an empty document, that has no name.
@@ -1628,7 +1628,7 @@ private:
     }
     @endverbatim
 */
-class TiXmlHandle
+class EXPCL_PANDA TiXmlHandle
 {
 public:
     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
@@ -1727,7 +1727,7 @@ private:
     fprintf( stdout, "%s", printer.CStr() );
     @endverbatim
 */
-class TiXmlPrinter : public TiXmlVisitor
+class EXPCL_PANDA TiXmlPrinter : public TiXmlVisitor
 {
 public:
     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),

+ 2 - 2
panda/src/egg/eggGroupNode_ext.cxx

@@ -17,7 +17,7 @@
 #ifdef HAVE_PYTHON
 
 #ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject Dtool_EggNode;
+extern struct Dtool_PyTypedObject Dtool_EggNode;
 #endif
 
 ////////////////////////////////////////////////////////////////////
@@ -37,7 +37,7 @@ get_children() const {
   }
 
   // Fill in the list.
-  int i = 0;
+  size_t i = 0;
   for (it = _this->begin(); it != _this->end() && i < len; ++it) {
     EggNode *node = *it;
     node->ref();

+ 119 - 0
panda/src/egg/eggVertex.cxx

@@ -398,6 +398,125 @@ clear_aux(const string &name) {
   _aux_map.erase(name);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggVertex::make_average
+//       Access: Published, Static
+//  Description: Creates a new vertex that lies in between the two
+//               given vertices.  The attributes for the UV sets
+//               they have in common are averaged.
+//
+//               Both vertices need to be either in no pool, or in
+//               the same pool.  In the latter case, the new vertex
+//               will be placed in that pool.
+///////////////////////////////////////////////////////////////////
+PT(EggVertex) EggVertex::
+make_average(const EggVertex *first, const EggVertex *second) {
+  PT(EggVertexPool) pool = first->get_pool();
+  nassertr(pool == second->get_pool(), NULL);
+
+  // If both vertices are in a pool, the new vertex will be part of
+  // the pool as well.
+  PT(EggVertex) middle;
+  if (pool == NULL) {
+    middle = new EggVertex;
+  } else {
+    middle = pool->make_new_vertex();
+  }
+
+  middle->set_pos4((first->get_pos4() + second->get_pos4()) / 2);
+
+  if (first->has_normal() && second->has_normal()) {
+    LNormald normal = (first->get_normal() + second->get_normal()) / 2;
+    normal.normalize();
+    middle->set_normal(normal);
+  }
+  if (first->has_color() && second->has_color()) {
+    middle->set_color((first->get_color() + second->get_color()) / 2);
+  }
+
+  // Average out the EggVertexUV objects, but only for the UV sets
+  // that they have in common.
+  const_uv_iterator it;
+  for (it = first->uv_begin(); it != first->uv_end(); ++it) {
+    const EggVertexUV *first_uv = it->second;
+    const EggVertexUV *second_uv = second->get_uv_obj(it->first);
+
+    if (first_uv != NULL && second_uv != NULL) {
+      middle->set_uv_obj(EggVertexUV::make_average(first_uv, second_uv));
+    }
+  }
+
+  // Same for EggVertexAux.
+  const_aux_iterator ai;
+  for (ai = first->aux_begin(); ai != first->aux_end(); ++ai) {
+    const EggVertexAux *first_aux = ai->second;
+    const EggVertexAux *second_aux = second->get_aux_obj(ai->first);
+
+    if (first_aux != NULL && second_aux != NULL) {
+      middle->set_aux_obj(EggVertexAux::make_average(first_aux, second_aux));
+    }
+  }
+
+  // Now process the morph targets.
+  EggMorphVertexList::const_iterator vi, vi2;
+  for (vi = first->_dxyzs.begin(); vi != first->_dxyzs.end(); ++vi) {
+    for (vi2 = second->_dxyzs.begin(); vi2 != second->_dxyzs.end(); ++vi2) {
+      if (vi->get_name() == vi2->get_name()) {
+        middle->_dxyzs.insert(EggMorphVertex(vi->get_name(),
+                              (vi->get_offset() + vi2->get_offset()) / 2));
+        break;
+      }
+    }
+  }
+
+  EggMorphNormalList::const_iterator ni, ni2;
+  for (ni = first->_dxyzs.begin(); ni != first->_dxyzs.end(); ++ni) {
+    for (ni2 = second->_dxyzs.begin(); ni2 != second->_dxyzs.end(); ++ni2) {
+      if (ni->get_name() == ni2->get_name()) {
+        middle->_dnormals.insert(EggMorphNormal(ni->get_name(),
+                                 (ni->get_offset() + ni2->get_offset()) / 2));
+        break;
+      }
+    }
+  }
+
+  EggMorphColorList::const_iterator ci, ci2;
+  for (ci = first->_drgbas.begin(); ci != first->_drgbas.end(); ++ci) {
+    for (ci2 = second->_drgbas.begin(); ci2 != second->_drgbas.end(); ++ci2) {
+      if (ci->get_name() == ci2->get_name()) {
+        middle->_drgbas.insert(EggMorphColor(ci->get_name(),
+                               (ci->get_offset() + ci2->get_offset()) / 2));
+        break;
+      }
+    }
+  }
+
+  // Now merge the vertex memberships.
+  GroupRef::iterator gi;
+  for (gi = first->_gref.begin(); gi != first->_gref.end(); ++gi) {
+    EggGroup *group = *gi;
+    if (second->_gref.count(group)) {
+      group->set_vertex_membership(middle,
+        (group->get_vertex_membership(first) +
+         group->get_vertex_membership(second)) / 2.);
+    } else {
+      // Hmm, unfortunate, only one of the vertices is member of this
+      // group, so we can't make an average.  We'll have to assign the
+      // only group membership we have.
+      group->set_vertex_membership(middle, group->get_vertex_membership(first));
+    }
+  }
+  // Also assign memberships to the grefs in the second vertex that
+  // aren't part of the first vertex.
+  for (gi = second->_gref.begin(); gi != second->_gref.end(); ++gi) {
+    EggGroup *group = *gi;
+    if (second->_gref.count(group) == 0) {
+      group->set_vertex_membership(middle, group->get_vertex_membership(second));
+    }
+  }
+
+  return middle;
+}
 
 ///////////////////////////////////////////////////////////////////
 //       Class : GroupRefEntry

+ 3 - 0
panda/src/egg/eggVertex.h

@@ -109,6 +109,9 @@ PUBLISHED:
   void set_aux_obj(EggVertexAux *vertex_aux);
   void clear_aux(const string &name);
 
+  static PT(EggVertex) make_average(const EggVertex *first,
+                                    const EggVertex *second);
+
 public:
   INLINE const_uv_iterator uv_begin() const;
   INLINE const_uv_iterator uv_end() const;

+ 20 - 5
panda/src/egg/eggVertexAux.cxx

@@ -22,7 +22,7 @@ TypeHandle EggVertexAux::_type_handle;
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexAux::Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexAux::
 EggVertexAux(const string &name, const LVecBase4d &aux) :
@@ -34,7 +34,7 @@ EggVertexAux(const string &name, const LVecBase4d &aux) :
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexAux::Copy Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexAux::
 EggVertexAux(const EggVertexAux &copy) :
@@ -46,7 +46,7 @@ EggVertexAux(const EggVertexAux &copy) :
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexAux::Copy Assignment Operator
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexAux &EggVertexAux::
 operator = (const EggVertexAux &copy) {
@@ -59,16 +59,31 @@ operator = (const EggVertexAux &copy) {
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexAux::Destructor
 //       Access: Published, Virtual
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexAux::
 ~EggVertexAux() {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggVertexAux::make_average
+//       Access: Published, Static
+//  Description: Creates a new EggVertexAux that contains the
+//               averaged values of the two given objects.  It is
+//               an error if they don't have the same name.
+///////////////////////////////////////////////////////////////////
+PT(EggVertexAux) EggVertexAux::
+make_average(const EggVertexAux *first, const EggVertexAux *second) {
+  nassertr(first->get_name() == second->get_name(), NULL);
+
+  LVecBase4d aux = (first->_aux + second->_aux) / 2;
+  return new EggVertexAux(first->get_name(), aux);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexAux::write
 //       Access: Public
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void EggVertexAux::
 write(ostream &out, int indent_level) const {

+ 3 - 0
panda/src/egg/eggVertexAux.h

@@ -42,6 +42,9 @@ PUBLISHED:
   INLINE const LVecBase4d &get_aux() const;
   INLINE void set_aux(const LVecBase4d &aux);
 
+  static PT(EggVertexAux) make_average(const EggVertexAux *first,
+                                       const EggVertexAux *second);
+
   void write(ostream &out, int indent_level) const;
   int compare_to(const EggVertexAux &other) const;
 

+ 31 - 6
panda/src/egg/eggVertexUV.cxx

@@ -22,7 +22,7 @@ TypeHandle EggVertexUV::_type_handle;
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexUV::
 EggVertexUV(const string &name, const LTexCoordd &uv) :
@@ -38,7 +38,7 @@ EggVertexUV(const string &name, const LTexCoordd &uv) :
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexUV::
 EggVertexUV(const string &name, const LTexCoord3d &uvw) :
@@ -54,7 +54,7 @@ EggVertexUV(const string &name, const LTexCoord3d &uvw) :
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::Copy Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexUV::
 EggVertexUV(const EggVertexUV &copy) :
@@ -70,7 +70,7 @@ EggVertexUV(const EggVertexUV &copy) :
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::Copy Assignment Operator
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexUV &EggVertexUV::
 operator = (const EggVertexUV &copy) {
@@ -87,12 +87,37 @@ operator = (const EggVertexUV &copy) {
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::Destructor
 //       Access: Published, Virtual
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 EggVertexUV::
 ~EggVertexUV() {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggVertexUV::make_average
+//       Access: Published, Static
+//  Description: Creates a new EggVertexUV that contains the
+//               averaged values of the two given objects.  It is
+//               an error if they don't have the same name.
+///////////////////////////////////////////////////////////////////
+PT(EggVertexUV) EggVertexUV::
+make_average(const EggVertexUV *first, const EggVertexUV *second) {
+  nassertr(first->get_name() == second->get_name(), NULL);
+  int flags = first->_flags & second->_flags;
+
+  LTexCoord3d uvw = (first->_uvw + second->_uvw) / 2;
+
+  PT(EggVertexUV) new_obj = new EggVertexUV(first->get_name(), uvw);
+  new_obj->_flags = flags;
+  new_obj->_tangent = (first->_tangent + second->_tangent) / 2;
+  new_obj->_binormal = (first->_binormal + second->_binormal) / 2;
+
+  // Normalize because we're polite.
+  new_obj->_tangent.normalize();
+  new_obj->_binormal.normalize();
+  return new_obj;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::transform
 //       Access: Published, Virtual
@@ -115,7 +140,7 @@ transform(const LMatrix4d &mat) {
 ////////////////////////////////////////////////////////////////////
 //     Function: EggVertexUV::write
 //       Access: Public
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void EggVertexUV::
 write(ostream &out, int indent_level) const {

+ 3 - 0
panda/src/egg/eggVertexUV.h

@@ -57,6 +57,9 @@ PUBLISHED:
   INLINE void set_binormal(const LNormald &binormal);
   INLINE void clear_binormal();
 
+  static PT(EggVertexUV) make_average(const EggVertexUV *first,
+                                      const EggVertexUV *second);
+
   void transform(const LMatrix4d &mat);
 
   void write(ostream &out, int indent_level) const;

+ 29 - 28
panda/src/egg2pg/eggLoader.cxx

@@ -2855,9 +2855,8 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
 //               This box is used by make_collision_box.
 ////////////////////////////////////////////////////////////////////
 bool EggLoader::
-make_box(EggGroup *egg_group, EggGroup::CollideFlags flags, 
-            LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
-  bool success = false;
+make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
+         LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
   if (geom_group != (EggGroup *)NULL) {
     // Collect all of the vertices.
@@ -2875,36 +2874,38 @@ make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
     }
 
     // Now find the min/max points
-    int num_vertices = 0;
-    bool first = true;
     pset<EggVertex *>::const_iterator vi;
-    for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
-      EggVertex *vtx = (*vi);
-      LVertex pos = LCAST(PN_stdfloat, vtx->get_pos3());
+    vi = vertices.begin();
 
-      if (first) {
-        min_p.set(pos[0], pos[1], pos[2]);
-        max_p.set(pos[0], pos[1], pos[2]);
-        first = false;
-      } else {
-        min_p.set(min(min_p[0], pos[0]),
-                  min(min_p[1], pos[1]),
-                  min(min_p[2], pos[2]));
-        max_p.set(max(max_p[0], pos[0]),
-                  max(max_p[1], pos[1]),
-                  max(max_p[2], pos[2]));
-      }
-      num_vertices++;
+    if (vi == vertices.end()) {
+      // No vertices, no bounding box.
+      min_p.set(0, 0, 0);
+      max_p.set(0, 0, 0);
+      return false;
     }
 
-    if (num_vertices > 1) {
-      vi = vertices.begin();
-      EggVertex *clr_vtx = (*vi);
-      color = clr_vtx->get_color();
-      success = true;
-    }
+    EggVertex *vertex = (*vi);
+    LVertexd min_pd = vertex->get_pos3();
+    LVertexd max_pd = min_pd;
+    color = vertex->get_color();
+
+    for (++vi; vi != vertices.end(); ++vi) {
+      vertex = (*vi);
+      const LVertexd &pos = vertex->get_pos3();
+      min_pd.set(min(min_pd[0], pos[0]),
+                 min(min_pd[1], pos[1]),
+                 min(min_pd[2], pos[2]));
+      max_pd.set(max(max_pd[0], pos[0]),
+                 max(max_pd[1], pos[1]),
+                 max(max_pd[2], pos[2]));
+    }
+
+    LMatrix4d mat = egg_group->get_vertex_to_node();
+    min_p = LCAST(PN_stdfloat, min_pd * mat);
+    max_p = LCAST(PN_stdfloat, max_pd * mat);
+    return (min_pd != max_pd);
   }
-  return success;
+  return false;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 2
panda/src/event/Sources.pp

@@ -20,7 +20,7 @@
     genericAsyncTask.h genericAsyncTask.I \
     pointerEvent.I pointerEvent.h \
     pointerEventList.I pointerEventList.h \
-    pythonTask.h pythonTask.I \
+    pythonTask.h pythonTask.I pythonTask.cxx \
     event.I event.h eventHandler.h eventHandler.I \
     eventParameter.I eventParameter.h \
     eventQueue.I eventQueue.h eventReceiver.h \
@@ -38,7 +38,6 @@
     genericAsyncTask.cxx \
     pointerEvent.cxx \
     pointerEventList.cxx \
-    pythonTask.cxx \
     config_event.cxx event.cxx eventHandler.cxx \ 
     eventParameter.cxx eventQueue.cxx eventReceiver.cxx \
     pt_Event.cxx

+ 0 - 4
panda/src/event/config_event.cxx

@@ -24,7 +24,6 @@
 #include "eventParameter.h"
 #include "genericAsyncTask.h"
 #include "pointerEventList.h"
-#include "pythonTask.h"
 
 #include "dconfig.h"
 
@@ -45,9 +44,6 @@ ConfigureFn(config_event) {
   EventStoreInt::init_type("EventStoreInt");
   EventStoreDouble::init_type("EventStoreDouble");
   GenericAsyncTask::init_type();
-#ifdef HAVE_PYTHON
-  PythonTask::init_type();
-#endif
 
   ButtonEventList::register_with_read_factory();
   EventStoreInt::register_with_read_factory();

+ 0 - 1
panda/src/event/p3event_composite1.cxx

@@ -9,4 +9,3 @@
 #include "genericAsyncTask.cxx"
 #include "pointerEvent.cxx"
 #include "pointerEventList.cxx"
-#include "pythonTask.cxx"

+ 7 - 2
panda/src/event/pythonTask.cxx

@@ -17,12 +17,17 @@
 #include "config_event.h"
 
 #ifdef HAVE_PYTHON
-#include "py_panda.h" 
+#include "py_panda.h"
 
 TypeHandle PythonTask::_type_handle;
 
+Configure(config_pythonTask);
+ConfigureFn(config_pythonTask) {
+  PythonTask::init_type();
+}
+
 #ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
+extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
 #endif
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/event/pythonTask.h

@@ -25,7 +25,7 @@
 // Description : This class exists to allow association of a Python
 //               function with the AsyncTaskManager.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA_PIPELINE PythonTask : public AsyncTask {
+class PythonTask : public AsyncTask {
 PUBLISHED:
   PythonTask(PyObject *function = Py_None, const string &name = string());
   virtual ~PythonTask();

+ 3 - 2
panda/src/express/dcast.cxx

@@ -16,11 +16,12 @@
 #include "config_express.h"
 
 #ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>  // for IsBadWritePtr()
 #endif
 
-
 #ifdef DO_DCAST
 ////////////////////////////////////////////////////////////////////
 //     Function: _dcast_verify

+ 0 - 48
panda/src/express/multifile.I

@@ -534,51 +534,3 @@ get_last_byte_pos() const {
   return max(_index_start + (streampos)_index_length, 
              _data_start + (streampos)_data_length) - (streampos)1;
 }
-
-#ifdef HAVE_OPENSSL
-////////////////////////////////////////////////////////////////////
-//     Function: Multifile::CertRecord::Constructor
-//       Access: Public
-//  Description: Ownership of the X509 object is passed into the
-//               CertRecord; it will be freed when the CertRecord
-//               destructs.
-////////////////////////////////////////////////////////////////////
-INLINE Multifile::CertRecord::
-CertRecord(X509 *cert) :
-  _cert(cert)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: Multifile::CertRecord::Copy Constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE Multifile::CertRecord::
-CertRecord(const Multifile::CertRecord &copy) :
-  _cert(X509_dup(copy._cert))
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: Multifile::CertRecord::Destructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE Multifile::CertRecord::
-~CertRecord() {
-  X509_free(_cert);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: Multifile::CertRecord::Copy Assignment
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE void Multifile::CertRecord::
-operator = (const Multifile::CertRecord &other) {
-  X509_free(_cert);
-  _cert = X509_dup(other._cert);
-}
-#endif
-

+ 47 - 0
panda/src/express/multifile.cxx

@@ -604,6 +604,53 @@ update_subfile(const string &subfile_name, const Filename &filename,
   return name;
 }
 
+#ifdef HAVE_OPENSSL
+////////////////////////////////////////////////////////////////////
+//     Function: Multifile::CertRecord::Constructor
+//       Access: Public
+//  Description: Ownership of the X509 object is passed into the
+//               CertRecord; it will be freed when the CertRecord
+//               destructs.
+////////////////////////////////////////////////////////////////////
+Multifile::CertRecord::
+CertRecord(X509 *cert) :
+  _cert(cert)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Multifile::CertRecord::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+Multifile::CertRecord::
+CertRecord(const Multifile::CertRecord &copy) :
+  _cert(X509_dup(copy._cert))
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Multifile::CertRecord::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+Multifile::CertRecord::
+~CertRecord() {
+  X509_free(_cert);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Multifile::CertRecord::Copy Assignment
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void Multifile::CertRecord::
+operator = (const Multifile::CertRecord &other) {
+  X509_free(_cert);
+  _cert = X509_dup(other._cert);
+}
+#endif  // HAVE_OPENSSL
+
 #ifdef HAVE_OPENSSL
 ////////////////////////////////////////////////////////////////////
 //     Function: Multifile::add_signature

+ 194 - 194
panda/src/express/ordered_vector.I

@@ -18,8 +18,8 @@
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ordered_vector<Key, Compare, Vector>::
 ordered_vector(TypeHandle type_handle) :
   _compare(Compare()),
   _vector(type_handle)
@@ -31,8 +31,8 @@ ordered_vector(TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ordered_vector<Key, Compare, Vector>::
 ordered_vector(const Compare &compare, TypeHandle type_handle) :
   _compare(compare),
   _vector(type_handle)
@@ -44,9 +44,9 @@ ordered_vector(const Compare &compare, TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ordered_vector<Key, Compare>::
-ordered_vector(const ordered_vector<Key, Compare> &copy) :
+template<class Key, class Compare, class Vector>
+INLINE ordered_vector<Key, Compare, Vector>::
+ordered_vector(const ordered_vector<Key, Compare, Vector> &copy) :
   _compare(copy._compare),
   _vector(copy._vector)
 {
@@ -57,9 +57,9 @@ ordered_vector(const ordered_vector<Key, Compare> &copy) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ordered_vector<Key, Compare> &ordered_vector<Key, Compare>::
-operator = (const ordered_vector<Key, Compare> &copy) {
+template<class Key, class Compare, class Vector>
+INLINE ordered_vector<Key, Compare, Vector> &ordered_vector<Key, Compare, Vector>::
+operator = (const ordered_vector<Key, Compare, Vector> &copy) {
   _compare = copy._compare;
   _vector = copy._vector;
   return *this;
@@ -70,8 +70,8 @@ operator = (const ordered_vector<Key, Compare> &copy) {
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ordered_vector<Key, Compare, Vector>::
 ~ordered_vector() {
 }
 
@@ -81,8 +81,8 @@ INLINE ordered_vector<Key, Compare>::
 //  Description: Returns the iterator that marks the first element in
 //               the ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
 begin() {
   return _vector.begin();
 }
@@ -93,8 +93,8 @@ begin() {
 //  Description: Returns the iterator that marks the end of the
 //               ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
 end() {
   return _vector.end();
 }
@@ -105,8 +105,8 @@ end() {
 //  Description: Returns the iterator that marks the first element in
 //               the ordered vector, when viewed in reverse order.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::REVERSE_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
 rbegin() {
   return _vector.rbegin();
 }
@@ -117,8 +117,8 @@ rbegin() {
 //  Description: Returns the iterator that marks the end of the
 //               ordered vector, when viewed in reverse order.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::REVERSE_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
 rend() {
   return _vector.rend();
 }
@@ -129,8 +129,8 @@ rend() {
 //  Description: Returns the iterator that marks the first element in
 //               the ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
 begin() const {
   return _vector.begin();
 }
@@ -141,8 +141,8 @@ begin() const {
 //  Description: Returns the iterator that marks the end of the
 //               ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
 end() const {
   return _vector.end();
 }
@@ -153,8 +153,8 @@ end() const {
 //  Description: Returns the iterator that marks the first element in
 //               the ordered vector, when viewed in reverse order.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
 rbegin() const {
   return _vector.rbegin();
 }
@@ -165,8 +165,8 @@ rbegin() const {
 //  Description: Returns the iterator that marks the end of the
 //               ordered vector, when viewed in reverse order.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
 rend() const {
   return _vector.rend();
 }
@@ -176,9 +176,9 @@ rend() const {
 //       Access: Public
 //  Description: Returns the nth element.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::REFERENCE ordered_vector<Key, Compare>::
-operator [] (TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REFERENCE ordered_vector<Key, Compare, Vector>::
+operator [] (TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE n) {
   return _vector[n];
 }
 
@@ -187,9 +187,9 @@ operator [] (TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) {
 //       Access: Public
 //  Description: Returns the nth element.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_REFERENCE ordered_vector<Key, Compare>::
-operator [] (TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) const {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REFERENCE ordered_vector<Key, Compare, Vector>::
+operator [] (TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE n) const {
   return _vector[n];
 }
 
@@ -198,8 +198,8 @@ operator [] (TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) const {
 //       Access: Public
 //  Description: Returns the number of elements in the ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Compare, Vector>::
 size() const {
   return _vector.size();
 }
@@ -210,8 +210,8 @@ size() const {
 //  Description: Returns the maximum number of elements that can
 //               possibly be stored in an ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Compare, Vector>::
 max_size() const {
   return _vector.max_size();
 }
@@ -222,8 +222,8 @@ max_size() const {
 //  Description: Returns true if the ordered vector is empty, false
 //               otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
 empty() const {
   return _vector.empty();
 }
@@ -234,9 +234,9 @@ empty() const {
 //  Description: Returns true if the two ordered vectors are
 //               memberwise equivalent, false otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator == (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator == (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector == other._vector;
 }
 
@@ -246,9 +246,9 @@ operator == (const ordered_vector<Key, Compare> &other) const {
 //  Description: Returns true if the two ordered vectors are not
 //               memberwise equivalent, false if they are.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator != (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator != (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector != other._vector;
 }
 
@@ -259,9 +259,9 @@ operator != (const ordered_vector<Key, Compare> &other) const {
 //               lexicographically before the other one, false
 //               otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator < (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator < (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector < other._vector;
 }
 
@@ -272,9 +272,9 @@ operator < (const ordered_vector<Key, Compare> &other) const {
 //               lexicographically after the other one, false
 //               otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator > (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator > (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector > other._vector;
 }
 
@@ -285,9 +285,9 @@ operator > (const ordered_vector<Key, Compare> &other) const {
 //               lexicographically before the other one or is
 //               equivalent, false otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator <= (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator <= (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector <= other._vector;
 }
 
@@ -298,9 +298,9 @@ operator <= (const ordered_vector<Key, Compare> &other) const {
 //               lexicographically after the other one or is
 //               equivalent, false otherwise.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ordered_vector<Key, Compare>::
-operator >= (const ordered_vector<Key, Compare> &other) const {
+template<class Key, class Compare, class Vector>
+INLINE bool ordered_vector<Key, Compare, Vector>::
+operator >= (const ordered_vector<Key, Compare, Vector> &other) const {
   return _vector >= other._vector;
 }
 
@@ -318,9 +318,9 @@ operator >= (const ordered_vector<Key, Compare> &other) const {
 //               original element), and the second componet is true if
 //               the insert operation has taken place.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE pair<TYPENAME ordered_vector<Key, Compare>::ITERATOR, bool> ordered_vector<Key, Compare>::
-insert_unique(const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE pair<TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR, bool> ordered_vector<Key, Compare, Vector>::
+insert_unique(const TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE &key) {
   TAU_PROFILE("ordered_vector::insert_unique(const value_type &)", " ", TAU_USER);
   ITERATOR position = find_insert_position(begin(), end(), key);
 #ifdef NDEBUG
@@ -351,9 +351,9 @@ insert_unique(const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
 //               The return value is the iterator referencing the new
 //               element.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-insert_nonunique(const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+insert_nonunique(const TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE &key) {
   TAU_PROFILE("ordered_vector::insert_nonunique(const value_type &)", " ", TAU_USER);
   ITERATOR position = find_insert_position(begin(), end(), key);
   nassertr(position >= begin() && position <= end(), end());
@@ -371,10 +371,10 @@ insert_nonunique(const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
 //               already verified that this is the correct sorting
 //               position; no checks are made.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-insert_unverified(TYPENAME ordered_vector<Key, Compare>::ITERATOR position, 
-                  const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+insert_unverified(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR position, 
+                  const TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE &key) {
   TAU_PROFILE("ordered_vector::insert_unverified(iterator, const value_type &)", " ", TAU_USER);
   ITERATOR result = _vector.insert(position, key);
   return result;
@@ -386,9 +386,9 @@ insert_unverified(TYPENAME ordered_vector<Key, Compare>::ITERATOR position,
 //  Description: Removes the element indicated by the given iterator,
 //               and returns the next sequential iterator.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-erase(TYPENAME ordered_vector<Key, Compare>::ITERATOR position) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+erase(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR position) {
   TAU_PROFILE("ordered_vector::erase(iterator)", " ", TAU_USER);
   SIZE_TYPE count = position - begin();
   _vector.erase(position);
@@ -401,9 +401,9 @@ erase(TYPENAME ordered_vector<Key, Compare>::ITERATOR position) {
 //  Description: Removes all elements matching the indicated key;
 //               returns the number of elements removed.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE ordered_vector<Key, Compare>::
-erase(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Compare, Vector>::
+erase(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::erase(const key_type &)", " ", TAU_USER);
   pair<ITERATOR, ITERATOR> result = equal_range(key);
   SIZE_TYPE count = result.second - result.first;
@@ -417,10 +417,10 @@ erase(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //  Description: Removes all elements indicated by the given iterator
 //               range.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
-erase(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
-      TYPENAME ordered_vector<Key, Compare>::ITERATOR last) {
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
+erase(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR first,
+      TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR last) {
   TAU_PROFILE("ordered_vector::erase(iterator, iterator)", " ", TAU_USER);
   _vector.erase(first, last);
 }
@@ -430,8 +430,8 @@ erase(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
 //       Access: Public
 //  Description: Removes all elements from the ordered vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
 clear() {
   TAU_PROFILE("ordered_vector::clear()", " ", TAU_USER);
   _vector.erase(_vector.begin(), _vector.end());
@@ -445,9 +445,9 @@ clear() {
 //               is not.  If there are multiple elements matching the
 //               key, the particular iterator returned is not defined.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-find(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+find(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::find(const key_type &)", " ", TAU_USER);
   return nci(r_find(begin(), end(), end(), key));
 }
@@ -460,9 +460,9 @@ find(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //               is not.  If there are multiple elements matching the
 //               key, the particular iterator returned is not defined.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-find(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+find(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   TAU_PROFILE("ordered_vector::find(const key_type &)", " ", TAU_USER);
   return r_find(begin(), end(), end(), key);
 }
@@ -483,9 +483,9 @@ find(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
 //               The assumption is that == implies !Compare(a, b) and
 //               !Compare(b, a), but not necessarily the converse.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-find_particular(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+find_particular(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::find_particular(const key_type &)", " ", TAU_USER);
   return nci(r_find_particular(begin(), end(), end(), key));
 }
@@ -503,9 +503,9 @@ find_particular(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //               multiple matches exist within the vector, the
 //               particular iterator returned is not defined./
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-find_particular(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+find_particular(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   TAU_PROFILE("ordered_vector::find_particular(const key_type &)", " ", TAU_USER);
   return r_find_particular(begin(), end(), end(), key);
 }
@@ -516,8 +516,8 @@ find_particular(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) cons
 //  Description: Returns the number of elements that sort equivalent
 //               to the key that are in the vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Compare, Vector>::
 count(const key_type &key) const {
   TAU_PROFILE("ordered_vector::count(const key_type &)", " ", TAU_USER);
   return r_count(begin(), end(), key);
@@ -529,9 +529,9 @@ count(const key_type &key) const {
 //  Description: Returns the iterator for the first element not less
 //               than key, or end() if all elements are less than key.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-lower_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+lower_bound(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::lower_bound(const key_type &)", " ", TAU_USER);
   return nci(r_lower_bound(begin(), end(), key));
 }
@@ -542,9 +542,9 @@ lower_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //  Description: Returns the iterator for the first element not less
 //               than key, or end() if all elements are less than key.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-lower_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+lower_bound(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   TAU_PROFILE("ordered_vector::lower_bound(const key_type &)", " ", TAU_USER);
   return r_lower_bound(begin(), end(), key);
 }
@@ -556,9 +556,9 @@ lower_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
 //               than key, or end() if no element is greater than
 //               key.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-upper_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+upper_bound(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::upper_bound(const key_type &)", " ", TAU_USER);
   return nci(r_upper_bound(begin(), end(), key));
 }
@@ -570,9 +570,9 @@ upper_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //               than key, or end() if no element is greater than
 //               key.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-upper_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+upper_bound(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   TAU_PROFILE("ordered_vector::upper_bound(const key_type &)", " ", TAU_USER);
   return r_upper_bound(begin(), end(), key);
 }
@@ -582,13 +582,13 @@ upper_bound(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
 //       Access: Public
 //  Description: Returns the pair (lower_bound(key), upper_bound(key)).
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE pair<TYPENAME ordered_vector<Key, Compare>::ITERATOR, TYPENAME ordered_vector<Key, Compare>::ITERATOR> ordered_vector<Key, Compare>::
-equal_range(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE pair<TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR> ordered_vector<Key, Compare, Vector>::
+equal_range(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   TAU_PROFILE("ordered_vector::equal_range(const key_type &)", " ", TAU_USER);
-  pair<TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR> result;
+  pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> result;
   result = r_equal_range(begin(), end(), key);
-  return pair<TYPENAME ordered_vector<Key, Compare>::ITERATOR, TYPENAME ordered_vector<Key, Compare>::ITERATOR>(nci(result.first), nci(result.second));
+  return pair<TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR>(nci(result.first), nci(result.second));
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -596,9 +596,9 @@ equal_range(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
 //       Access: Public
 //  Description: Returns the pair (lower_bound(key), upper_bound(key)).
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE pair<TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR> ordered_vector<Key, Compare>::
-equal_range(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+INLINE pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> ordered_vector<Key, Compare, Vector>::
+equal_range(const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   TAU_PROFILE("ordered_vector::equal_range(const key_type &)", " ", TAU_USER);
   return r_equal_range(begin(), end(), key);
 }
@@ -609,9 +609,9 @@ equal_range(const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
 //  Description: Exchanges the contents of this vector and the other
 //               vector, in constant time (e.g., with a pointer swap).
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
-swap(ordered_vector<Key, Compare> &copy) {
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
+swap(ordered_vector<Key, Compare, Vector> &copy) {
   TAU_PROFILE("ordered_vector::swap(ordered_vector &)", " ", TAU_USER);
   _vector.swap(copy._vector);
 }
@@ -623,9 +623,9 @@ swap(ordered_vector<Key, Compare> &copy) {
 //               ensures that the capacity of the vector is greater
 //               than or equal to n.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
-reserve(TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) {
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
+reserve(TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE n) {
   TAU_PROFILE("ordered_vector::reserve(size_type)", " ", TAU_USER);
   _vector.reserve(n);
 }
@@ -642,8 +642,8 @@ reserve(TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE n) {
 //               This flavor of sort also eliminates repeated
 //               elements.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
 sort_unique() {
   TAU_PROFILE("ordered_vector::sort_unique()", " ", TAU_USER);
   sort(begin(), end(), _compare);
@@ -660,8 +660,8 @@ sort_unique() {
 //               written to the vector using the non-const iterators
 //               or has called push_back().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
 sort_nonunique() {
   TAU_PROFILE("ordered_vector::sort_nonunique()", " ", TAU_USER);
   stable_sort(begin(), end(), _compare);
@@ -675,8 +675,8 @@ sort_nonunique() {
 //               except to populate the vector the first time; be sure
 //               to call sort() after you have added all the elements.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
 push_back(const value_type &key) {
   TAU_PROFILE("ordered_vector::push_back()", " ", TAU_USER);
   _vector.push_back(key);
@@ -687,8 +687,8 @@ push_back(const value_type &key) {
 //       Access: Public
 //  Description: Removes the last element at the end of the vector.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ordered_vector<Key, Compare, Vector>::
 pop_back() {
   TAU_PROFILE("ordered_vector::pop_back()", " ", TAU_USER);
   _vector.pop_back();
@@ -702,9 +702,9 @@ pop_back() {
 //               easy definition of const vs. non-const flavors of
 //               some of these methods.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-nci(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR i) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+nci(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR i) {
   return begin() + (i - begin());
 }
 
@@ -715,11 +715,11 @@ nci(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR i) {
 //               vector to insert the indicated key, and returns the
 //               corresponding iterator.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-find_insert_position(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
-                     TYPENAME ordered_vector<Key, Compare>::ITERATOR last,
-                     const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+find_insert_position(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR first,
+                     TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR last,
+                     const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   ITERATOR result = r_find_insert_position(first, last, key);
   return result;
 }
@@ -729,10 +729,10 @@ find_insert_position(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_set<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ov_set<Key, Compare, Vector>::
 ov_set(TypeHandle type_handle) :
-  ordered_vector<Key, Compare>(type_handle)
+  ordered_vector<Key, Compare, Vector>(type_handle)
 {
 }
 
@@ -741,10 +741,10 @@ ov_set(TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_set<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ov_set<Key, Compare, Vector>::
 ov_set(const Compare &compare, TypeHandle type_handle) :
-  ordered_vector<Key, Compare>(compare, type_handle)
+  ordered_vector<Key, Compare, Vector>(compare, type_handle)
 {
 }
 
@@ -753,10 +753,10 @@ ov_set(const Compare &compare, TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_set<Key, Compare>::
-ov_set(const ov_set<Key, Compare> &copy) :
-  ordered_vector<Key, Compare>(copy)
+template<class Key, class Compare, class Vector>
+INLINE ov_set<Key, Compare, Vector>::
+ov_set(const ov_set<Key, Compare, Vector> &copy) :
+  ordered_vector<Key, Compare, Vector>(copy)
 {
 }
 
@@ -765,10 +765,10 @@ ov_set(const ov_set<Key, Compare> &copy) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_set<Key, Compare> &ov_set<Key, Compare>::
-operator = (const ov_set<Key, Compare> &copy) {
-  ordered_vector<Key, Compare>::operator = (copy);
+template<class Key, class Compare, class Vector>
+INLINE ov_set<Key, Compare, Vector> &ov_set<Key, Compare, Vector>::
+operator = (const ov_set<Key, Compare, Vector> &copy) {
+  ordered_vector<Key, Compare, Vector>::operator = (copy);
   return *this;
 }
 
@@ -777,11 +777,11 @@ operator = (const ov_set<Key, Compare> &copy) {
 //       Access: Public
 //  Description: Maps to insert_unique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ov_set<Key, Compare>::ITERATOR ov_set<Key, Compare>::
-insert(TYPENAME ov_set<Key, Compare>::ITERATOR position, 
-       const TYPENAME ov_set<Key, Compare>::VALUE_TYPE &key) {
-  return ordered_vector<Key, Compare>::insert_unique(position, key);
+template<class Key, class Compare, class Vector>
+TYPENAME ov_set<Key, Compare, Vector>::ITERATOR ov_set<Key, Compare, Vector>::
+insert(TYPENAME ov_set<Key, Compare, Vector>::ITERATOR position, 
+       const TYPENAME ov_set<Key, Compare, Vector>::VALUE_TYPE &key) {
+  return ordered_vector<Key, Compare, Vector>::insert_unique(position, key);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -789,10 +789,10 @@ insert(TYPENAME ov_set<Key, Compare>::ITERATOR position,
 //       Access: Public
 //  Description: Maps to insert_unique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE pair<TYPENAME ov_set<Key, Compare>::ITERATOR, bool> ov_set<Key, Compare>::
-insert(const TYPENAME ov_set<Key, Compare>::VALUE_TYPE &key) {
-  return ordered_vector<Key, Compare>::insert_unique(key);
+template<class Key, class Compare, class Vector>
+INLINE pair<TYPENAME ov_set<Key, Compare, Vector>::ITERATOR, bool> ov_set<Key, Compare, Vector>::
+insert(const TYPENAME ov_set<Key, Compare, Vector>::VALUE_TYPE &key) {
+  return ordered_vector<Key, Compare, Vector>::insert_unique(key);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -800,10 +800,10 @@ insert(const TYPENAME ov_set<Key, Compare>::VALUE_TYPE &key) {
 //       Access: Public
 //  Description: Maps to sort_unique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ov_set<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ov_set<Key, Compare, Vector>::
 sort() {
-  ordered_vector<Key, Compare>::sort_unique();
+  ordered_vector<Key, Compare, Vector>::sort_unique();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -811,10 +811,10 @@ sort() {
 //       Access: Public
 //  Description: Maps to verify_list_unique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ov_set<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE bool ov_set<Key, Compare, Vector>::
 verify_list() const {
-  return ordered_vector<Key, Compare>::verify_list_unique();
+  return ordered_vector<Key, Compare, Vector>::verify_list_unique();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -822,10 +822,10 @@ verify_list() const {
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_multiset<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ov_multiset<Key, Compare, Vector>::
 ov_multiset(TypeHandle type_handle) :
-  ordered_vector<Key, Compare>(type_handle)
+  ordered_vector<Key, Compare, Vector>(type_handle)
 {
 }
 
@@ -834,10 +834,10 @@ ov_multiset(TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_multiset<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE ov_multiset<Key, Compare, Vector>::
 ov_multiset(const Compare &compare, TypeHandle type_handle) :
-  ordered_vector<Key, Compare>(compare, type_handle)
+  ordered_vector<Key, Compare, Vector>(compare, type_handle)
 {
 }
 
@@ -846,10 +846,10 @@ ov_multiset(const Compare &compare, TypeHandle type_handle) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_multiset<Key, Compare>::
-ov_multiset(const ov_multiset<Key, Compare> &copy) :
-  ordered_vector<Key, Compare>(copy)
+template<class Key, class Compare, class Vector>
+INLINE ov_multiset<Key, Compare, Vector>::
+ov_multiset(const ov_multiset<Key, Compare, Vector> &copy) :
+  ordered_vector<Key, Compare, Vector>(copy)
 {
 }
 
@@ -858,10 +858,10 @@ ov_multiset(const ov_multiset<Key, Compare> &copy) :
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE ov_multiset<Key, Compare> &ov_multiset<Key, Compare>::
-operator = (const ov_multiset<Key, Compare> &copy) {
-  ordered_vector<Key, Compare>::operator = (copy);
+template<class Key, class Compare, class Vector>
+INLINE ov_multiset<Key, Compare, Vector> &ov_multiset<Key, Compare, Vector>::
+operator = (const ov_multiset<Key, Compare, Vector> &copy) {
+  ordered_vector<Key, Compare, Vector>::operator = (copy);
   return *this;
 }
 
@@ -870,11 +870,11 @@ operator = (const ov_multiset<Key, Compare> &copy) {
 //       Access: Public
 //  Description: Maps to insert_nonunique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ov_multiset<Key, Compare>::ITERATOR ov_multiset<Key, Compare>::
-insert(TYPENAME ov_multiset<Key, Compare>::ITERATOR position, 
-       const TYPENAME ov_multiset<Key, Compare>::VALUE_TYPE &key) {
-  return ordered_vector<Key, Compare>::insert_nonunique(position, key);
+template<class Key, class Compare, class Vector>
+TYPENAME ov_multiset<Key, Compare, Vector>::ITERATOR ov_multiset<Key, Compare, Vector>::
+insert(TYPENAME ov_multiset<Key, Compare, Vector>::ITERATOR position, 
+       const TYPENAME ov_multiset<Key, Compare, Vector>::VALUE_TYPE &key) {
+  return ordered_vector<Key, Compare, Vector>::insert_nonunique(position, key);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -882,10 +882,10 @@ insert(TYPENAME ov_multiset<Key, Compare>::ITERATOR position,
 //       Access: Public
 //  Description: Maps to insert_nonunique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE TYPENAME ov_multiset<Key, Compare>::ITERATOR ov_multiset<Key, Compare>::
-insert(const TYPENAME ov_multiset<Key, Compare>::VALUE_TYPE &key) {
-  return ordered_vector<Key, Compare>::insert_nonunique(key);
+template<class Key, class Compare, class Vector>
+INLINE TYPENAME ov_multiset<Key, Compare, Vector>::ITERATOR ov_multiset<Key, Compare, Vector>::
+insert(const TYPENAME ov_multiset<Key, Compare, Vector>::VALUE_TYPE &key) {
+  return ordered_vector<Key, Compare, Vector>::insert_nonunique(key);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -893,10 +893,10 @@ insert(const TYPENAME ov_multiset<Key, Compare>::VALUE_TYPE &key) {
 //       Access: Public
 //  Description: Maps to sort_nonunique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE void ov_multiset<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE void ov_multiset<Key, Compare, Vector>::
 sort() {
-  ordered_vector<Key, Compare>::sort_nonunique();
+  ordered_vector<Key, Compare, Vector>::sort_nonunique();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -904,8 +904,8 @@ sort() {
 //       Access: Public
 //  Description: Maps to verify_list_nonunique().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-INLINE bool ov_multiset<Key, Compare>::
+template<class Key, class Compare, class Vector>
+INLINE bool ov_multiset<Key, Compare, Vector>::
 verify_list() const {
-  return ordered_vector<Key, Compare>::verify_list_nonunique();
+  return ordered_vector<Key, Compare, Vector>::verify_list_nonunique();
 }

+ 51 - 51
panda/src/express/ordered_vector.T

@@ -27,10 +27,10 @@
 //               already present, it is not inserted, and the iterator
 //               referencing the original value is returned.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-insert_unique(TYPENAME ordered_vector<Key, Compare>::ITERATOR position, 
-              const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+insert_unique(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR position, 
+              const TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE &key) {
   TAU_PROFILE("ordered_vector::insert_unique(iterator, const value_type &)", " ", TAU_USER);
   if (position != end()) {
     // If we're not inserting at the end, the element we're
@@ -74,10 +74,10 @@ insert_unique(TYPENAME ordered_vector<Key, Compare>::ITERATOR position,
 //               This flavor of insert allows multiple copies of the
 //               same key to be inserted.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-insert_nonunique(TYPENAME ordered_vector<Key, Compare>::ITERATOR position, 
-                 const TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE &key) {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+insert_nonunique(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR position, 
+                 const TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE &key) {
   TAU_PROFILE("ordered_vector::insert_nonunique(iterator, const value_type &)", " ", TAU_USER);
   if (position != end()) {
     // If we're not inserting at the end, the element we're
@@ -107,8 +107,8 @@ insert_nonunique(TYPENAME ordered_vector<Key, Compare>::ITERATOR position,
 //               sorted correctly.  Returns true if this is the case;
 //               otherwise, returns false.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-bool ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+bool ordered_vector<Key, Compare, Vector>::
 verify_list_unique() const {
   TAU_PROFILE("ordered_vector::verify_list_unique()", " ", TAU_USER);
   if (!empty()) {
@@ -134,8 +134,8 @@ verify_list_unique() const {
 //               sorted correctly.  Returns true if this is the case;
 //               otherwise, returns false.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-bool ordered_vector<Key, Compare>::
+template<class Key, class Compare, class Vector>
+bool ordered_vector<Key, Compare, Vector>::
 verify_list_nonunique() const {
   TAU_PROFILE("ordered_vector::verify_list_nonunique()", " ", TAU_USER);
   if (!empty()) {
@@ -161,11 +161,11 @@ verify_list_nonunique() const {
 //  Description: The recursive implementation of
 //               find_insert_position().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::ITERATOR ordered_vector<Key, Compare>::
-r_find_insert_position(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
-                       TYPENAME ordered_vector<Key, Compare>::ITERATOR last,
-                       const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ordered_vector<Key, Compare, Vector>::
+r_find_insert_position(TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR first,
+                       TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR last,
+                       const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) {
   if (first == last) {
     // The list is empty; the insert position is the last of the list.
     return last;
@@ -189,12 +189,12 @@ r_find_insert_position(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of find().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-r_find(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-       TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-       TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR not_found,
-       const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+r_find(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+       TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+       TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR not_found,
+       const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   if (first == last) {
     // The list is empty; the key is not on the list.
     return not_found;
@@ -222,12 +222,12 @@ r_find(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of find_particular().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-r_find_particular(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-                  TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-                  TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR not_found,
-                  const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+r_find_particular(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+                  TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+                  TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR not_found,
+                  const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   if (first == last) {
     // The list is empty; the key is not on the list.
     return not_found;
@@ -275,12 +275,12 @@ r_find_particular(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of count().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::SIZE_TYPE ordered_vector<Key, Compare>::
-r_count(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-        TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-        const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
-  typedef pair<TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR> pair_type;
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Compare, Vector>::
+r_count(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+        TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+        const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
+  typedef pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> pair_type;
 
   if (first == last) {
     // The list is empty; the key is not on the list.
@@ -311,11 +311,11 @@ r_count(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of lower_bound().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-r_lower_bound(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-              TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-              const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+r_lower_bound(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+              TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+              const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   if (first == last) {
     // The list is empty; the key is not on the list.
     return last;
@@ -344,11 +344,11 @@ r_lower_bound(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of upper_bound().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR ordered_vector<Key, Compare>::
-r_upper_bound(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-              TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-              const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
+template<class Key, class Compare, class Vector>
+TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
+r_upper_bound(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+              TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+              const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
   if (first == last) {
     // The list is empty; the key is not on the list.
     return last;
@@ -377,12 +377,12 @@ r_upper_bound(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
 //       Access: Private
 //  Description: The recursive implementation of equal_range().
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare>
-pair<TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR> ordered_vector<Key, Compare>::
-r_equal_range(TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR first,
-              TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR last,
-              const TYPENAME ordered_vector<Key, Compare>::KEY_TYPE &key) const {
-  typedef pair<TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare>::CONST_ITERATOR> pair_type;
+template<class Key, class Compare, class Vector>
+pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> ordered_vector<Key, Compare, Vector>::
+r_equal_range(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
+              TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
+              const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
+  typedef pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> pair_type;
 
   if (first == last) {
     // The list is empty; the key is not on the list.

+ 25 - 28
panda/src/express/ordered_vector.h

@@ -21,15 +21,15 @@
 // on pc cygwin from  3 minutes to 17 seconds ?? really need to explore interigate to figure out what is 
 // going on ..
 //
-template<class Key, class Compare = less<int> > class ov_multiset
+template<class Key, class Compare = less<int>, class Vector = pvector<Key> > class ov_multiset
 {
 };
 
-template<class Key, class Compare = less<int> > class ov_set
+template<class Key, class Compare = less<int>, class Vector = pvector<Key> > class ov_set
 {
 };
 
-template<class Key, class Compare = less<int> > class ordered_vector
+template<class Key, class Compare = less<int>, class Vector = pvector<Key> > class ordered_vector
 {
 };
 
@@ -105,11 +105,8 @@ template<class Key, class Compare = less<int> > class ordered_vector
 //               (4) Random access into the set is easy with the []
 //               operator.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare = less<Key> >
+template<class Key, class Compare = less<Key>, class Vector = pvector<Key> >
 class ordered_vector {
-private:
-  typedef pvector<Key> Vector;
-  
 public:
   // Typedefs
   typedef Key KEY_TYPE;
@@ -152,8 +149,8 @@ public:
   INLINE ordered_vector(TypeHandle type_handle = ov_set_type_handle);
   INLINE ordered_vector(const Compare &compare,
                         TypeHandle type_handle = ov_set_type_handle);
-  INLINE ordered_vector(const ordered_vector<Key, Compare> &copy);
-  INLINE ordered_vector<Key, Compare> &operator = (const ordered_vector<Key, Compare> &copy);
+  INLINE ordered_vector(const ordered_vector<Key, Compare, Vector> &copy);
+  INLINE ordered_vector<Key, Compare, Vector> &operator = (const ordered_vector<Key, Compare, Vector> &copy);
   INLINE ~ordered_vector();
 
   // Iterator access.
@@ -177,13 +174,13 @@ public:
   INLINE bool empty() const;
 
   // Equivalence and lexicographical comparisons.
-  INLINE bool operator == (const ordered_vector<Key, Compare> &other) const;
-  INLINE bool operator != (const ordered_vector<Key, Compare> &other) const;
+  INLINE bool operator == (const ordered_vector<Key, Compare, Vector> &other) const;
+  INLINE bool operator != (const ordered_vector<Key, Compare, Vector> &other) const;
 
-  INLINE bool operator < (const ordered_vector<Key, Compare> &other) const;
-  INLINE bool operator > (const ordered_vector<Key, Compare> &other) const;
-  INLINE bool operator <= (const ordered_vector<Key, Compare> &other) const;
-  INLINE bool operator >= (const ordered_vector<Key, Compare> &other) const;
+  INLINE bool operator < (const ordered_vector<Key, Compare, Vector> &other) const;
+  INLINE bool operator > (const ordered_vector<Key, Compare, Vector> &other) const;
+  INLINE bool operator <= (const ordered_vector<Key, Compare, Vector> &other) const;
+  INLINE bool operator >= (const ordered_vector<Key, Compare, Vector> &other) const;
 
   // Insert operations.
   ITERATOR insert_unique(ITERATOR position, const VALUE_TYPE &key);
@@ -213,7 +210,7 @@ public:
   INLINE pair<CONST_ITERATOR, CONST_ITERATOR> equal_range(const KEY_TYPE &key) const;
 
   // Special operations.
-  INLINE void swap(ordered_vector<Key, Compare> &other);
+  INLINE void swap(ordered_vector<Key, Compare, Vector> &other);
   INLINE void reserve(SIZE_TYPE n);
   INLINE void sort_unique();
   INLINE void sort_nonunique();
@@ -273,17 +270,17 @@ private:
 //               standard STL set: one copy of each element is
 //               allowed.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare = less<Key> >
-class ov_set : public ordered_vector<Key, Compare> {
+template<class Key, class Compare = less<Key>, class Vector = pvector<Key> >
+class ov_set : public ordered_vector<Key, Compare, Vector> {
 public:
-  typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
-  typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
+  typedef TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ITERATOR;
+  typedef TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE VALUE_TYPE;
 
   INLINE ov_set(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_set(const Compare &compare,
                 TypeHandle type_handle = ov_set_type_handle);
-  INLINE ov_set(const ov_set<Key, Compare> &copy);
-  INLINE ov_set<Key, Compare> &operator = (const ov_set<Key, Compare> &copy);
+  INLINE ov_set(const ov_set<Key, Compare, Vector> &copy);
+  INLINE ov_set<Key, Compare, Vector> &operator = (const ov_set<Key, Compare, Vector> &copy);
 
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
   INLINE pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
@@ -298,17 +295,17 @@ public:
 //               standard STL set: many copies of each element are
 //               allowed.
 ////////////////////////////////////////////////////////////////////
-template<class Key, class Compare = less<Key> >
-class ov_multiset : public ordered_vector<Key, Compare> {
+template<class Key, class Compare = less<Key>, class Vector = pvector<Key> >
+class ov_multiset : public ordered_vector<Key, Compare, Vector> {
 public:
-  typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
-  typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
+  typedef TYPENAME ordered_vector<Key, Compare, Vector>::ITERATOR ITERATOR;
+  typedef TYPENAME ordered_vector<Key, Compare, Vector>::VALUE_TYPE VALUE_TYPE;
 
   INLINE ov_multiset(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_multiset(const Compare &compare,
                      TypeHandle type_handle = ov_set_type_handle);
-  INLINE ov_multiset(const ov_multiset<Key, Compare> &copy);
-  INLINE ov_multiset<Key, Compare> &operator = (const ov_multiset<Key, Compare> &copy);
+  INLINE ov_multiset(const ov_multiset<Key, Compare, Vector> &copy);
+  INLINE ov_multiset<Key, Compare, Vector> &operator = (const ov_multiset<Key, Compare, Vector> &copy);
 
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
   INLINE ITERATOR insert(const VALUE_TYPE &key);

+ 3 - 2
panda/src/express/password_hash.h

@@ -23,8 +23,9 @@
 
 BEGIN_PUBLISH
 
-string password_hash(const string &password, const string &salt, 
-                     int iters, int keylen);
+EXPCL_PANDAEXPRESS string password_hash(const string &password,
+                                        const string &salt,
+                                        int iters, int keylen);
 
 END_PUBLISH
 

+ 1 - 324
panda/src/express/pointerToArray.I

@@ -39,7 +39,7 @@ PointerToArray(TypeHandle type_handle) :
 //  Description: Return an empty array of size n
 ////////////////////////////////////////////////////////////////////
 template<class Element>
-INLINE PointerToArray<Element> 
+INLINE PointerToArray<Element>
 PointerToArray<Element>::empty_array(size_type n, TypeHandle type_handle) {
   PointerToArray<Element> temp(type_handle);
   temp.reassign(new ReferenceCountedVector<Element>(type_handle));
@@ -77,129 +77,6 @@ PointerToArray(const PointerToArray<Element> &copy) :
 {
 }
 
-#ifdef HAVE_PYTHON
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::Constructor
-//       Access: Published
-//  Description: This special constructor accepts a Python list of
-//               elements, or a Python string (or a bytes object,
-//               in Python 3), or any object that supports the
-//               Python buffer protocol.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-PointerToArray<Element>::
-PointerToArray(PyObject *self, PyObject *source) :
-  PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL),
-  _type_handle(get_type_handle(Element))
-{
-  // We have to pre-initialize self's "this" pointer when we receive
-  // self in the constructor--the caller can't initialize this for us.
-  ((Dtool_PyInstDef *)self)->_ptr_to_object = this;
-
-#if PY_VERSION_HEX >= 0x02060000
-  if (PyObject_CheckBuffer(source)) {
-    // User passed a buffer object.
-    Py_buffer view;
-    if (PyObject_GetBuffer(source, &view, PyBUF_CONTIG_RO) == -1) {
-      PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a contiguous buffer");
-      return;
-    }
-
-    if (view.itemsize != 1 && view.itemsize != sizeof(Element)) {
-      PyErr_SetString(PyExc_TypeError, "buffer.itemsize does not match PointerToArray element size");
-      return;
-    }
-
-    int num_elements = view.len / sizeof(Element);
-    insert(begin(), num_elements, Element());
-
-    if (view.len > 0) {
-      memcpy(p(), view.buf, view.len);
-    }
-
-    PyBuffer_Release(&view);
-    return;
-  }
-#endif
-
-  if (!PySequence_Check(source)) {
-    // If passed with a non-sequence, this isn't the right constructor.
-    PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence or buffer object");
-    return;
-  }
-
-  // If we were passed a Python string, then instead of storing it
-  // character-at-a-time, just load the whole string as a data
-  // buffer.
-#if PY_MAJOR_VERSION >= 3
-  if (PyBytes_Check(source)) {
-    int size = PyBytes_Size(source);
-    if (size % sizeof(Element) != 0) {
-      ostringstream stream;
-      stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
-      string str = stream.str();
-      PyErr_SetString(PyExc_ValueError, str.c_str());
-      return;
-    }
-      
-    int num_elements = size / sizeof(Element);
-    insert(begin(), num_elements, Element());
-
-    // Hope there aren't any constructors or destructors involved
-    // here.
-    if (size != 0) {
-      const char *data = PyBytes_AsString(source);
-      memcpy(p(), data, size);
-    }
-    return;
-  }
-#else
-  if (PyString_CheckExact(source)) {
-    int size = PyString_Size(source);
-    if (size % sizeof(Element) != 0) {
-      ostringstream stream;
-      stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
-      string str = stream.str();
-      PyErr_SetString(PyExc_ValueError, str.c_str());
-      return;
-    }
-
-    int num_elements = size / sizeof(Element);
-    insert(begin(), num_elements, Element());
-
-    // Hope there aren't any constructors or destructors involved
-    // here.
-    if (size != 0) {
-      const char *data = PyString_AsString(source);
-      memcpy(p(), data, size);
-    }
-    return;
-  }
-#endif
-
-  // Now construct the internal list by copying the elements
-  // one-at-a-time from Python.
-  int size = PySequence_Size(source);
-  for (int i = 0; i < size; ++i) {
-    PyObject *item = PySequence_GetItem(source, i);
-    if (item == NULL) {
-      return;
-    }
-    PyObject *result = PyObject_CallMethod(self, (char *)"push_back", (char *)"O", item);
-    Py_DECREF(item);
-    if (result == NULL) {
-      // Unable to add item--probably it wasn't of the appropriate type.
-      ostringstream stream;
-      stream << "Element " << i << " in sequence passed to PointerToArray constructor could not be added";
-      string str = stream.str();
-      PyErr_SetString(PyExc_TypeError, str.c_str());
-      return;
-    }
-    Py_DECREF(result);
-  }
-}
-#endif  // HAVE_PYTHON
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArray::begin
 //       Access: Public
@@ -593,31 +470,6 @@ set_element(size_type n, const Element &value) {
   (*this)[n] = value;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::__getitem__
-//       Access: Published
-//  Description: Same as get_element(), this returns the nth element
-//               of the array.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE const Element &PointerToArray<Element>::
-__getitem__(size_type n) const {
-  return (*this)[n];
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::__setitem__
-//       Access: Published
-//  Description: Same as set_element(), this replaces the nth element
-//               of the array.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void PointerToArray<Element>::
-__setitem__(size_type n, const Element &value) {
-  nassertv(n < ((To *)(this->_void_ptr))->size());
-  (*this)[n] = value;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArray::get_data
 //       Access: Published
@@ -884,23 +736,6 @@ ConstPointerToArray(const ConstPointerToArray<Element> &copy) :
 {
 }
 
-#ifdef HAVE_PYTHON
-////////////////////////////////////////////////////////////////////
-//     Function: ConstPointerToArray::Constructor
-//       Access: Public
-//  Description: This special constructor accepts a Python list of
-//               elements, or a Python string (or a bytes object,
-//               in Python 3).
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE ConstPointerToArray<Element>::
-ConstPointerToArray(PyObject *self, PyObject *source) :
-  PointerToArrayBase<Element>(PointerToArray<Element>(self, source)),
-  _type_handle(get_type_handle(Element))
-{
-}
-#endif  // HAVE_PYTHON
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ConstPointerToArray::begin
 //       Access: Public
@@ -1158,18 +993,6 @@ get_element(size_type n) const {
   return (*this)[n];
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ConstPointerToArray::__getitem__
-//       Access: Published
-//  Description: Same as get_element(), this returns the nth element
-//               of the array.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE const Element &ConstPointerToArray<Element>::
-__getitem__(size_type n) const {
-  return (*this)[n];
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ConstPointerToArray::get_data
 //       Access: Published
@@ -1331,150 +1154,4 @@ clear() {
   ((ConstPointerToArray<Element> *)this)->reassign((ReferenceCountedVector<Element> *)NULL);
 }
 
-#ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::__getbuffer__
-//       Access: Published
-//  Description: This is used to implement the buffer protocol, in
-//               order to allow efficient access to the array data
-//               through a Python multiview object.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE int PointerToArray<Element>::
-__getbuffer__(PyObject *self, Py_buffer *view, int flags) {
-
-  const char *format = get_format_code(Element);
-  if (format == NULL) {
-    // Not supported.
-    return -1;
-  }
-
-  if (self != NULL) {
-    Py_INCREF(self);
-  }
-  view->obj = self;
-  view->buf = (void*) p();
-  view->len = size() * sizeof(Element);
-  view->readonly = 0;
-  view->itemsize = sizeof(Element);
-  view->format = NULL;
-  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
-    view->format = (char*) format;
-  }
-  view->ndim = 1;
-  view->shape = NULL;
-  if ((flags & PyBUF_ND) == PyBUF_ND) {
-    // This leaks, which sucks, but __releasebuffer__ doesn't give us
-    // the same pointer, so we would need to store it elsewhere if we
-    // wanted to delete it there.  Eh, it's just an int, who cares.
-    view->shape = new Py_ssize_t(size());
-  }
-  view->strides = NULL;
-  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
-    view->strides = &(view->itemsize);
-  }
-  view->suboffsets = NULL;
-
-  // Store a reference to ourselves on the Py_buffer object
-  // as a reminder that we have increased our refcount.
-  ref();
-  view->internal = (void*) this;
-
-  return 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::__releasebuffer__
-//       Access: Published
-//  Description: Releases the buffer allocated by __getbuffer__.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void PointerToArray<Element>::
-__releasebuffer__(PyObject *self, Py_buffer *view) const {
-  // Note: PyBuffer_Release automatically decrements view->obj.
-
-  if (view->internal != NULL) {
-    // Oh, right, let's not forget to unref this.
-    ((const PointerToArray<Element> *) view->internal)->unref();
-    view->internal = NULL;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ConstPointerToArray::__getbuffer__
-//       Access: Published
-//  Description: This is used to implement the buffer protocol, in
-//               order to allow efficient access to the array data
-//               through a Python multiview object.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE int ConstPointerToArray<Element>::
-__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
-
-  if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
-    PyErr_SetString(PyExc_BufferError,
-                    "Object is not writable.");
-    return -1;
-  }
-
-  const char *format = get_format_code(Element);
-  if (format == NULL) {
-    // Not supported.
-    return -1;
-  }
-
-  if (self != NULL) {
-    Py_INCREF(self);
-  }
-  view->obj = self;
-  view->buf = (void*) p();
-  view->len = size() * sizeof(Element);
-  view->readonly = 1;
-  view->itemsize = sizeof(Element);
-  view->format = NULL;
-  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
-    view->format = (char*) format;
-  }
-  view->ndim = 1;
-  view->shape = NULL;
-  if ((flags & PyBUF_ND) == PyBUF_ND) {
-    // This leaks, which sucks, but __releasebuffer__ doesn't give us
-    // the same pointer, so we would need to store it elsewhere if we
-    // wanted to delete it there.  Eh, it's just an int, who cares.
-    view->shape = new Py_ssize_t(size());
-  }
-  view->strides = NULL;
-  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
-    view->strides = &(view->itemsize);
-  }
-  view->suboffsets = NULL;
-
-  // Store a reference to ourselves on the Py_buffer object
-  // as a reminder that we have increased our refcount.
-  ref();
-  view->internal = (void*) this;
-
-  return 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ConstPointerToArray::__releasebuffer__
-//       Access: Published
-//  Description: Releases the buffer allocated by __getbuffer__.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void ConstPointerToArray<Element>::
-__releasebuffer__(PyObject *self, Py_buffer *view) const {
-  // Note: PyBuffer_Release automatically decrements obj->view.
-
-  if (view->internal != NULL) {
-    // Oh, right, let's not forget to unref this.
-    ((const PointerToArray<Element> *) view->internal)->unref();
-    view->internal = NULL;
-  }
-}
-#endif  // PY_VERSION_HEX
-#endif  // HAVE_PYTHON
-
 #endif  // CPPPARSER

+ 9 - 71
panda/src/express/pointerToArray.h

@@ -67,9 +67,6 @@
 #include "pandabase.h"
 
 #include "pointerToArrayBase.h"
-#ifdef HAVE_PYTHON
-#include "py_panda.h"
-#endif
 
 #if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER)
 // disable mysterious MSVC warning for static inline PTA::empty_array method
@@ -112,17 +109,15 @@ PUBLISHED:
   INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(const PointerToArray<Element> &copy);
 
-#ifdef HAVE_PYTHON
-  PointerToArray(PyObject *self, PyObject *source);
-#endif
+  EXTENSION(PointerToArray(PyObject *self, PyObject *source));
 
   INLINE size_type size() const;
   INLINE void push_back(const Element &x);
   INLINE void pop_back();
   INLINE const Element &get_element(size_type n) const;
   INLINE void set_element(size_type n, const Element &value);
-  INLINE const Element &__getitem__(size_type n) const;
-  INLINE void __setitem__(size_type n, const Element &value);
+  EXTENSION(const Element &__getitem__(size_type n) const);
+  EXTENSION(void __setitem__(size_type n, const Element &value));
   INLINE string get_data() const;
   INLINE void set_data(const string &data);
   INLINE string get_subdata(size_type n, size_type count) const;
@@ -132,8 +127,8 @@ PUBLISHED:
 
 #ifdef HAVE_PYTHON
 #if PY_VERSION_HEX >= 0x02060000
-  int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
-  void __releasebuffer__(PyObject *self, Py_buffer *view) const;
+  EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
+  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
 #endif
 
@@ -156,10 +151,6 @@ public:
   INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(const PointerToArray<Element> &copy);
 
-#ifdef HAVE_PYTHON
-  PointerToArray(PyObject *self, PyObject *source);
-#endif
-
 public:
   // Duplicating the interface of vector.  The following member
   // functions are all const, because they do not reassign the
@@ -213,8 +204,6 @@ public:
   // Methods to help out Python and other high-level languages.
   INLINE const Element &get_element(size_type n) const;
   INLINE void set_element(size_type n, const Element &value);
-  INLINE const Element &__getitem__(size_type n) const;
-  INLINE void __setitem__(size_type n, const Element &value);
   INLINE string get_data() const;
   INLINE void set_data(const string &data);
   INLINE string get_subdata(size_type n, size_type count) const;
@@ -237,13 +226,6 @@ public:
   INLINE void node_ref() const;
   INLINE bool node_unref() const;
 
-#ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
-  int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
-  void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
-#endif
-
   // Reassignment is by pointer, not memberwise as with a vector.
   INLINE PointerToArray<Element> &
   operator = (ReferenceCountedVector<Element> *ptr);
@@ -283,14 +265,12 @@ PUBLISHED:
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
 
-#ifdef HAVE_PYTHON
-  INLINE ConstPointerToArray(PyObject *self, PyObject *source);
-#endif
+  EXTENSION(ConstPointerToArray(PyObject *self, PyObject *source));
 
   typedef TYPENAME pvector<Element>::size_type size_type;
   INLINE size_type size() const;
   INLINE const Element &get_element(size_type n) const;
-  INLINE const Element &__getitem__(size_type n) const;
+  EXTENSION(const Element &__getitem__(size_type n) const);
   INLINE string get_data() const;
   INLINE string get_subdata(size_type n, size_type count) const;
   INLINE int get_ref_count() const;
@@ -298,8 +278,8 @@ PUBLISHED:
 
 #ifdef HAVE_PYTHON
 #if PY_VERSION_HEX >= 0x02060000
-  int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
-  void __releasebuffer__(PyObject *self, Py_buffer *view) const;
+  EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
+  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
 #endif
 
@@ -325,10 +305,6 @@ PUBLISHED:
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
 
-#ifdef HAVE_PYTHON
-  INLINE ConstPointerToArray(PyObject *self, PyObject *source);
-#endif
-
   // Duplicating the interface of vector.
 
   INLINE iterator begin() const;
@@ -361,7 +337,6 @@ PUBLISHED:
 
   // Methods to help out Python and other high-level languages.
   INLINE const Element &get_element(size_type n) const;
-  INLINE const Element &__getitem__(size_type n) const;
   INLINE string get_data() const;
   INLINE string get_subdata(size_type n, size_type count) const;
 
@@ -373,13 +348,6 @@ PUBLISHED:
   INLINE void node_ref() const;
   INLINE bool node_unref() const;
 
-#ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
-  int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
-  void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
-#endif
-
   // Reassignment is by pointer, not memberwise as with a vector.
   INLINE ConstPointerToArray<Element> &
   operator = (ReferenceCountedVector<Element> *ptr);
@@ -408,36 +376,6 @@ private:
 #define PTA(type) PointerToArray< type >
 #define CPTA(type) ConstPointerToArray< type >
 
-#ifdef HAVE_PYTHON
-// This macro is used to map a data type to a format code
-// as used in the Python 'struct' and 'array' modules.
-#define get_format_code(type) _get_format_code((const type *)0)
-#define define_format_code(code, type) template<> \
-  INLINE const char *_get_format_code(const type *) { \
-    return code; \
-  }
-
-template<class T>
-INLINE const char *_get_format_code(const T *) {
-  return NULL;
-}
-
-define_format_code("c", char);
-define_format_code("b", signed char);
-define_format_code("B", unsigned char);
-define_format_code("h", short);
-define_format_code("H", unsigned short);
-define_format_code("i", int);
-define_format_code("I", unsigned int);
-define_format_code("l", long);
-define_format_code("L", unsigned long);
-define_format_code("q", long long);
-define_format_code("Q", unsigned long long);
-define_format_code("f", float);
-define_format_code("d", double);
-
-#endif  // HAVE_PYTHON
-
 #include "pointerToArray.I"
 
 #endif  // HAVE_POINTERTOARRAY_H

+ 321 - 0
panda/src/express/pointerToArray_ext.I

@@ -0,0 +1,321 @@
+// Filename: pointerToArray_ext.I
+// Created by:  rdb (08Feb15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__init__
+//       Access: Published
+//  Description: This special constructor accepts a Python list of
+//               elements, or a Python string (or a bytes object,
+//               in Python 3), or any object that supports the
+//               Python buffer protocol.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+void Extension<PointerToArray<Element> >::
+__init__(PyObject *self, PyObject *source) {
+#if PY_VERSION_HEX >= 0x02060000
+  if (PyObject_CheckBuffer(source)) {
+    // User passed a buffer object.
+    Py_buffer view;
+    if (PyObject_GetBuffer(source, &view, PyBUF_CONTIG_RO) == -1) {
+      PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a contiguous buffer");
+      return;
+    }
+
+    if (view.itemsize != 1 && view.itemsize != sizeof(Element)) {
+      PyErr_SetString(PyExc_TypeError, "buffer.itemsize does not match PointerToArray element size");
+      return;
+    }
+
+    int num_elements = view.len / sizeof(Element);
+    this->_this->insert(this->_this->begin(), num_elements, Element());
+
+    if (view.len > 0) {
+      memcpy(this->_this->p(), view.buf, view.len);
+    }
+
+    PyBuffer_Release(&view);
+    return;
+  }
+#endif
+
+  if (!PySequence_Check(source)) {
+    // If passed with a non-sequence, this isn't the right constructor.
+    PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence or buffer object");
+    return;
+  }
+
+  // If we were passed a Python string, then instead of storing it
+  // character-at-a-time, just load the whole string as a data
+  // buffer.
+#if PY_MAJOR_VERSION >= 3
+  if (PyBytes_Check(source)) {
+    int size = PyBytes_Size(source);
+    if (size % sizeof(Element) != 0) {
+      ostringstream stream;
+      stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
+      string str = stream.str();
+      PyErr_SetString(PyExc_ValueError, str.c_str());
+      return;
+    }
+
+    int num_elements = size / sizeof(Element);
+    this->_this->insert(this->_this->begin(), num_elements, Element());
+
+    // Hope there aren't any constructors or destructors involved
+    // here.
+    if (size != 0) {
+      const char *data = PyBytes_AsString(source);
+      memcpy(this->_this->p(), data, size);
+    }
+    return;
+  }
+#else
+  if (PyString_CheckExact(source)) {
+    int size = PyString_Size(source);
+    if (size % sizeof(Element) != 0) {
+      ostringstream stream;
+      stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
+      string str = stream.str();
+      PyErr_SetString(PyExc_ValueError, str.c_str());
+      return;
+    }
+
+    int num_elements = size / sizeof(Element);
+    this->_this->insert(this->_this->begin(), num_elements, Element());
+
+    // Hope there aren't any constructors or destructors involved
+    // here.
+    if (size != 0) {
+      const char *data = PyString_AsString(source);
+      memcpy(this->_this->p(), data, size);
+    }
+    return;
+  }
+#endif
+
+  // Now construct the internal list by copying the elements
+  // one-at-a-time from Python.
+  int size = PySequence_Size(source);
+  for (int i = 0; i < size; ++i) {
+    PyObject *item = PySequence_GetItem(source, i);
+    if (item == NULL) {
+      return;
+    }
+    PyObject *result = PyObject_CallMethod(self, (char *)"push_back", (char *)"O", item);
+    Py_DECREF(item);
+    if (result == NULL) {
+      // Unable to add item--probably it wasn't of the appropriate type.
+      ostringstream stream;
+      stream << "Element " << i << " in sequence passed to PointerToArray constructor could not be added";
+      string str = stream.str();
+      PyErr_SetString(PyExc_TypeError, str.c_str());
+      return;
+    }
+    Py_DECREF(result);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__getitem__
+//       Access: Published
+//  Description: Same as get_element(), this returns the nth element
+//               of the array.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE const Element &Extension<PointerToArray<Element> >::
+__getitem__(size_t n) const {
+  return this->_this->get_element(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__setitem__
+//       Access: Published
+//  Description: Same as set_element(), this replaces the nth element
+//               of the array.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void Extension<PointerToArray<Element> >::
+__setitem__(size_t n, const Element &value) {
+  this->_this->set_element(n, value);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerToArray::__init__
+//       Access: Public
+//  Description: This special constructor accepts a Python list of
+//               elements, or a Python string (or a bytes object,
+//               in Python 3).
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void Extension<ConstPointerToArray<Element> >::
+__init__(PyObject *self, PyObject *source) {
+  new (this->_this) ConstPointerToArray<Element>(get_type_handle(Element));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerToArray::__getitem__
+//       Access: Published
+//  Description: Same as get_element(), this returns the nth element
+//               of the array.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE const Element &Extension<ConstPointerToArray<Element> >::
+__getitem__(size_t n) const {
+  return (*this->_this)[n];
+}
+
+#if PY_VERSION_HEX >= 0x02060000
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__getbuffer__
+//       Access: Published
+//  Description: This is used to implement the buffer protocol, in
+//               order to allow efficient access to the array data
+//               through a Python multiview object.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE int Extension<PointerToArray<Element> >::
+__getbuffer__(PyObject *self, Py_buffer *view, int flags) {
+
+  const char *format = get_format_code(Element);
+  if (format == NULL) {
+    // Not supported.
+    return -1;
+  }
+
+  if (self != NULL) {
+    Py_INCREF(self);
+  }
+  view->obj = self;
+  view->buf = (void*) this->_this->p();
+  view->len = this->_this->size() * sizeof(Element);
+  view->readonly = 0;
+  view->itemsize = sizeof(Element);
+  view->format = NULL;
+  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
+    view->format = (char*) format;
+  }
+  view->ndim = 1;
+  view->shape = NULL;
+  if ((flags & PyBUF_ND) == PyBUF_ND) {
+    // This leaks, which sucks, but __releasebuffer__ doesn't give us
+    // the same pointer, so we would need to store it elsewhere if we
+    // wanted to delete it there.  Eh, it's just an int, who cares.
+    view->shape = new Py_ssize_t(this->_this->size());
+  }
+  view->strides = NULL;
+  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
+    view->strides = &(view->itemsize);
+  }
+  view->suboffsets = NULL;
+
+  // Store a reference to ourselves on the Py_buffer object
+  // as a reminder that we have increased our refcount.
+  this->_this->ref();
+  view->internal = (void*) this->_this;
+
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::__releasebuffer__
+//       Access: Published
+//  Description: Releases the buffer allocated by __getbuffer__.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void Extension<PointerToArray<Element> >::
+__releasebuffer__(PyObject *self, Py_buffer *view) const {
+  // Note: PyBuffer_Release automatically decrements view->obj.
+
+  if (view->internal != NULL) {
+    // Oh, right, let's not forget to unref this.
+    ((const PointerToArray<Element> *) view->internal)->unref();
+    view->internal = NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerToArray::__getbuffer__
+//       Access: Published
+//  Description: This is used to implement the buffer protocol, in
+//               order to allow efficient access to the array data
+//               through a Python multiview object.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE int Extension<ConstPointerToArray<Element> >::
+__getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
+
+  if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
+    PyErr_SetString(PyExc_BufferError,
+                    "Object is not writable.");
+    return -1;
+  }
+
+  const char *format = get_format_code(Element);
+  if (format == NULL) {
+    // Not supported.
+    return -1;
+  }
+
+  if (self != NULL) {
+    Py_INCREF(self);
+  }
+  view->obj = self;
+  view->buf = (void*) this->_this->p();
+  view->len = this->_this->size() * sizeof(Element);
+  view->readonly = 1;
+  view->itemsize = sizeof(Element);
+  view->format = NULL;
+  if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
+    view->format = (char*) format;
+  }
+  view->ndim = 1;
+  view->shape = NULL;
+  if ((flags & PyBUF_ND) == PyBUF_ND) {
+    // This leaks, which sucks, but __releasebuffer__ doesn't give us
+    // the same pointer, so we would need to store it elsewhere if we
+    // wanted to delete it there.  Eh, it's just an int, who cares.
+    view->shape = new Py_ssize_t(this->_this->size());
+  }
+  view->strides = NULL;
+  if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
+    view->strides = &(view->itemsize);
+  }
+  view->suboffsets = NULL;
+
+  // Store a reference to ourselves on the Py_buffer object
+  // as a reminder that we have increased our refcount.
+  this->_this->ref();
+  view->internal = (void*) this->_this;
+
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerToArray::__releasebuffer__
+//       Access: Published
+//  Description: Releases the buffer allocated by __getbuffer__.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void Extension<ConstPointerToArray<Element> >::
+__releasebuffer__(PyObject *self, Py_buffer *view) const {
+  // Note: PyBuffer_Release automatically decrements obj->view.
+
+  if (view->internal != NULL) {
+    // Oh, right, let's not forget to unref this.
+    ((const PointerToArray<Element> *) view->internal)->unref();
+    view->internal = NULL;
+  }
+}
+#endif  // PY_VERSION_HEX

+ 100 - 0
panda/src/express/pointerToArray_ext.h

@@ -0,0 +1,100 @@
+// Filename: pointerToArray_ext.h
+// Created by:  rdb (08Feb15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef POINTERTOARRAY_EXT_H
+#define POINTERTOARRAY_EXT_H
+
+#ifndef CPPPARSER
+
+#include "extension.h"
+#include "py_panda.h"
+#include "pointerToArray.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : Extension<PointerToArray>
+// Description : This class defines the extension methods for
+//               PointerToArray, which are called instead of
+//               any C++ methods with the same prototype.
+//
+//               This is a little bit awkward because of the nested
+//               templating, but it does the job.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+class Extension<PointerToArray<Element> > : public ExtensionBase<PointerToArray<Element> > {
+public:
+  INLINE void __init__(PyObject *self, PyObject *source);
+
+  INLINE const Element &__getitem__(size_t n) const;
+  INLINE void __setitem__(size_t n, const Element &value);
+
+#if PY_VERSION_HEX >= 0x02060000
+  INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
+  INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
+#endif
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : Extension<ConstPointerToArray>
+// Description : This class defines the extension methods for
+//               ConstPointerToArray, which are called instead of
+//               any C++ methods with the same prototype.
+//
+//               This is a little bit awkward because of the nested
+//               templating, but it does the job.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+class Extension<ConstPointerToArray<Element> > : public ExtensionBase<ConstPointerToArray<Element> > {
+public:
+  INLINE void __init__(PyObject *self, PyObject *source);
+
+  INLINE const Element &__getitem__(size_t n) const;
+
+#if PY_VERSION_HEX >= 0x02060000
+  INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
+  INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
+#endif
+};
+
+// This macro is used to map a data type to a format code
+// as used in the Python 'struct' and 'array' modules.
+#define get_format_code(type) _get_format_code((const type *)0)
+#define define_format_code(code, type) template<> \
+  INLINE const char *_get_format_code(const type *) { \
+    return code; \
+  }
+
+template<class T>
+INLINE const char *_get_format_code(const T *) {
+  return NULL;
+}
+
+define_format_code("c", char);
+define_format_code("b", signed char);
+define_format_code("B", unsigned char);
+define_format_code("h", short);
+define_format_code("H", unsigned short);
+define_format_code("i", int);
+define_format_code("I", unsigned int);
+define_format_code("l", long);
+define_format_code("L", unsigned long);
+define_format_code("q", long long);
+define_format_code("Q", unsigned long long);
+define_format_code("f", float);
+define_format_code("d", double);
+
+#include "pointerToArray_ext.I"
+
+#endif  // CPPPARSER
+
+#endif  // HAVE_POINTERTOARRAY_EXT_H

+ 3 - 1
panda/src/express/trueClock.cxx

@@ -30,7 +30,9 @@ TrueClock *TrueClock::_global_ptr = NULL;
 ////////////////////////////////////////////////////////////////////
 
 #include <sys/timeb.h>
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 static const double _0001 = 1.0 / 1000.0;

+ 2 - 1
panda/src/express/virtualFileSystem_ext.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "virtualFileSystem_ext.h"
+#include "vector_uchar.h"
 
 #ifdef HAVE_PYTHON
 
@@ -30,7 +31,7 @@
 ////////////////////////////////////////////////////////////////////
 PyObject *Extension<VirtualFileSystem>::
 read_file(const Filename &filename, bool auto_unwrap) const {
-  pvector<unsigned char> pv;
+  vector_uchar pv;
   bool okflag = _this->read_file(filename, pv, auto_unwrap);
   nassertr(okflag, NULL);
 

+ 3 - 1
panda/src/express/windowsRegistry.cxx

@@ -17,7 +17,9 @@
 #include "textEncoder.h"
 
 #if defined(WIN32_VC)
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 
 ////////////////////////////////////////////////////////////////////

+ 99 - 39
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -215,72 +215,132 @@ issue_parameters(int altered) {
       switch (ptr_data->_type) {
       case Shader::SPT_float:
         switch(_ptr._info._class) {
-        case Shader::SAC_scalar: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
+        case Shader::SAC_scalar:
+          cgSetParameter1fv(p, (float*)ptr_data->_ptr);
+          continue;
+
         case Shader::SAC_vector:
           switch (_ptr._info._type) {
-          case Shader::SAT_vec1: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec2: cgSetParameter2fv(p,(float*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec3: cgSetParameter3fv(p,(float*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec4: cgSetParameter4fv(p,(float*)ptr_data->_ptr); continue;
-          default: nassertd(false) continue;
+          case Shader::SAT_vec1:
+            cgSetParameter1fv(p, (float*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec2:
+            cgSetParameter2fv(p, (float*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec3:
+            cgSetParameter3fv(p, (float*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec4:
+            cgSetParameter4fv(p, (float*)ptr_data->_ptr);
+            continue;
+          default:
+            nassertd(false) continue;
           }
-        case Shader::SAC_matrix: cgGLSetMatrixParameterfc(p,(float*)ptr_data->_ptr); continue;
-        case Shader::SAC_array: {
+          continue;
+
+        case Shader::SAC_matrix:
+          cgGLSetMatrixParameterfc(p, (float*)ptr_data->_ptr);
+          continue;
+
+        case Shader::SAC_array:
           switch (_ptr._info._subclass) {
           case Shader::SAC_scalar:
-            cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            cgGLSetParameterArray1f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr);
+            continue;
           case Shader::SAC_vector:
             switch (_ptr._dim[2]) {
-            case 1: cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
-            case 2: cgGLSetParameterArray2f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
-            case 3: cgGLSetParameterArray3f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
-            case 4: cgGLSetParameterArray4f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            case 1: cgGLSetParameterArray1f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+            case 2: cgGLSetParameterArray2f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+            case 3: cgGLSetParameterArray3f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+            case 4: cgGLSetParameterArray4f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+            default:
+              nassertd(_ptr._dim[2] > 0 && _ptr._dim[2] <= 4) continue;
             }
+            continue;
           case Shader::SAC_matrix:
-            cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            cgGLSetMatrixParameterArrayfc(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr);
+            continue;
+          default:
+            nassertd(false) continue;
           }
+        default:
+          nassertd(false) continue;
         }
-        }
+
       case Shader::SPT_double:
         switch(_ptr._info._class) {
-        case Shader::SAC_scalar: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
+        case Shader::SAC_scalar:
+          cgSetParameter1dv(p, (double*)ptr_data->_ptr);
+          continue;
+
         case Shader::SAC_vector:
-          switch(_ptr._info._type) {
-          case Shader::SAT_vec1: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec2: cgSetParameter2dv(p,(double*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec3: cgSetParameter3dv(p,(double*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec4: cgSetParameter4dv(p,(double*)ptr_data->_ptr); continue;
-          default: nassertd(false) continue;
+          switch (_ptr._info._type) {
+          case Shader::SAT_vec1:
+            cgSetParameter1dv(p, (double*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec2:
+            cgSetParameter2dv(p, (double*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec3:
+            cgSetParameter3dv(p, (double*)ptr_data->_ptr);
+            continue;
+          case Shader::SAT_vec4:
+            cgSetParameter4dv(p, (double*)ptr_data->_ptr);
+            continue;
+          default:
+            nassertd(false) continue;
           }
-        case Shader::SAC_matrix: cgGLSetMatrixParameterdc(p,(double*)ptr_data->_ptr); continue;
-        case Shader::SAC_array: {
-          switch(_ptr._info._subclass) {
+          continue;
+
+        case Shader::SAC_matrix:
+          cgGLSetMatrixParameterdc(p, (double*)ptr_data->_ptr);
+          continue;
+
+        case Shader::SAC_array:
+          switch (_ptr._info._subclass) {
           case Shader::SAC_scalar:
-            cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            cgGLSetParameterArray1d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr);
+            continue;
           case Shader::SAC_vector:
-            switch(_ptr._dim[2]) {
-            case 1: cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
-            case 2: cgGLSetParameterArray2d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
-            case 3: cgGLSetParameterArray3d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
-            case 4: cgGLSetParameterArray4d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            switch (_ptr._dim[2]) {
+            case 1: cgGLSetParameterArray1d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
+            case 2: cgGLSetParameterArray2d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
+            case 3: cgGLSetParameterArray3d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
+            case 4: cgGLSetParameterArray4d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
+            default:
+              nassertd(_ptr._dim[2] > 0 && _ptr._dim[2] <= 4) continue;
             }
+            continue;
           case Shader::SAC_matrix:
-            cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            cgGLSetMatrixParameterArraydc(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr);
+            continue;
+          default:
+            nassertd(false) continue;
           }
+        default:
+          nassertd(false) continue;
         }
-        }
+        continue;
+
       case Shader::SPT_int:
         switch(_ptr._info._class) {
-        case Shader::SAC_scalar: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
+        case Shader::SAC_scalar:
+          cgSetParameter1iv(p, (int*)ptr_data->_ptr);
+          continue;
         case Shader::SAC_vector:
           switch(_ptr._info._type) {
-          case Shader::SAT_vec1: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec2: cgSetParameter2iv(p,(int*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec3: cgSetParameter3iv(p,(int*)ptr_data->_ptr); continue;
-          case Shader::SAT_vec4: cgSetParameter4iv(p,(int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec1: cgSetParameter1iv(p, (int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec2: cgSetParameter2iv(p, (int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec3: cgSetParameter3iv(p, (int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec4: cgSetParameter4iv(p, (int*)ptr_data->_ptr); continue;
+          default:
+            nassertd(false) continue;
           }
+        default:
+          nassertd(false) continue;
         }
-      default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
+      default:
+        GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
         release_resources();
         return;
       }

+ 5 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -8811,6 +8811,11 @@ set_state_and_transform(const RenderState *target,
     //PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
     do_issue_clip_plane();
     _state_mask.set_bit(clip_plane_slot);
+#ifndef OPENGLES_1
+    if (_current_shader_context) {
+      _current_shader_context->issue_parameters(Shader::SSD_clip_planes);
+    }
+#endif
   }
 
   int color_slot = ColorAttrib::get_class_slot();

+ 19 - 0
panda/src/glstuff/glShaderContext_src.cxx

@@ -412,6 +412,25 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
             s->_mat_spec.push_back(bind);
             continue;
           }
+          if (noprefix == "ClipPlane") {
+            for (int i = 0; i < param_size; ++i) {
+              Shader::ShaderMatSpec bind;
+              bind._id = arg_id;
+              bind._id._seqno = seqno++;
+              bind._piece = Shader::SMP_row3;
+              bind._func = Shader::SMF_first;
+              bind._index = i;
+              bind._part[0] = Shader::SMO_apiview_clipplane_i;
+              bind._arg[0] = NULL;
+              bind._dep[0] = Shader::SSD_general | Shader::SSD_clip_planes;
+              bind._part[1] = Shader::SMO_identity;
+              bind._arg[1] = NULL;
+              bind._dep[1] = Shader::SSD_NONE;
+              s->_mat_spec.push_back(bind);
+              _glsl_parameter_map.push_back(p + i);
+            }
+            continue;
+          }
           if (noprefix == "LightModel.ambient") {
             Shader::ShaderMatSpec bind;
             bind._id = arg_id;

+ 8 - 4
panda/src/gobj/Sources.pp

@@ -8,7 +8,8 @@
   #define LOCAL_LIBS \
     p3pstatclient p3event p3linmath p3mathutil p3pnmimage p3gsgbase p3putil
 
-  #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx 
+  #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx \
+                           $[TARGET]_ext_composite.cxx
 
   #define SOURCES \
     adaptiveLru.I adaptiveLru.h \
@@ -30,7 +31,7 @@
     geomLinestrips.h \
     geomPoints.h \
     geomVertexArrayData.h geomVertexArrayData.I \
-    geomVertexArrayData_ext.h geomVertexArrayData_ext.cxx \
+    geomVertexArrayData_ext.h \
     geomVertexArrayFormat.h geomVertexArrayFormat.I \
     geomCacheEntry.h geomCacheEntry.I \
     geomCacheManager.h geomCacheManager.I \
@@ -43,7 +44,7 @@
     geomVertexWriter.h geomVertexWriter.I \
     indexBufferContext.I indexBufferContext.h \
     internalName.I internalName.h \
-    internalName_ext.h internalName_ext.cxx \
+    internalName_ext.h \
     lens.h lens.I \
     material.I material.h materialPool.I materialPool.h  \
     matrixLens.I matrixLens.h \
@@ -82,7 +83,7 @@
     vertexSlider.I vertexSlider.h \
     vertexTransform.I vertexTransform.h \
     videoTexture.I videoTexture.h
-    
+
   #define INCLUDED_SOURCES \
     adaptiveLru.cxx \
     animateVerticesRequest.cxx \
@@ -103,6 +104,7 @@
     geomLinestrips.cxx \
     geomPoints.cxx \
     geomVertexArrayData.cxx \
+    geomVertexArrayData_ext.cxx \
     geomVertexArrayFormat.cxx \
     geomCacheEntry.cxx \
     geomCacheManager.cxx \
@@ -116,6 +118,7 @@
     indexBufferContext.cxx \
     material.cxx  \
     internalName.cxx \
+    internalName_ext.cxx \
     lens.cxx  \
     materialPool.cxx matrixLens.cxx \
     occlusionQueryContext.cxx \
@@ -131,6 +134,7 @@
     sliderTable.cxx \
     texture.cxx \
     textureCollection.cxx \
+    textureCollection_ext.cxx \
     textureContext.cxx \
     texturePeeker.cxx \
     texturePool.cxx \

+ 1 - 1
panda/src/gobj/geomVertexData.cxx

@@ -369,7 +369,7 @@ unclean_set_format(const GeomVertexFormat *format) {
   // Assign the new format.
   cdataw->_format = format;
 
-  for (int ai = 0; ai < cdataw->_arrays.size(); ++ai) {
+  for (size_t ai = 0; ai < cdataw->_arrays.size(); ++ai) {
     PT(GeomVertexArrayData) array_obj = cdataw->_arrays[ai].get_write_pointer();
     array_obj->_array_format = format->get_array(ai);
   }

+ 3 - 0
panda/src/gobj/p3gobj_ext_composite.cxx

@@ -0,0 +1,3 @@
+#include "internalName_ext.cxx"
+#include "geomVertexArrayData_ext.cxx"
+#include "textureCollection_ext.cxx"

+ 1 - 1
panda/src/gobj/shader.I

@@ -866,7 +866,7 @@ get_filename_from_index(int index, ShaderType type) const {
       return fn;
     }
   } else if (glsl_preprocess && index > 2048 &&
-             (index - 2048) < _included_files.size()) {
+             (index - 2048) < (int)_included_files.size()) {
     return _included_files[index - 2048];
   }
   // Must be a mistake.  Quietly put back the integer.

+ 9 - 3
panda/src/gobj/shader.cxx

@@ -27,10 +27,13 @@ TypeHandle Shader::_type_handle;
 Shader::ShaderTable Shader::_load_table;
 Shader::ShaderTable Shader::_make_table;
 Shader::ShaderCaps Shader::_default_caps;
-CGcontext Shader::_cg_context = 0;
 int Shader::_shaders_generated;
 ShaderUtilization Shader::_shader_utilization = SUT_unspecified;
 
+#ifdef HAVE_CG
+CGcontext Shader::_cg_context = 0;
+#endif
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Shader::cp_report_error
 //       Access: Public
@@ -424,7 +427,6 @@ cp_dependency(ShaderMatInput inp) {
       (inp == SMO_mat_constant_x) ||
       (inp == SMO_vec_constant_x) ||
       (inp == SMO_vec_constant_x_attrib) ||
-      (inp == SMO_clipplane_x) ||
       (inp == SMO_view_x_to_view) ||
       (inp == SMO_view_to_view_x) ||
       (inp == SMO_apiview_x_to_view) ||
@@ -444,6 +446,10 @@ cp_dependency(ShaderMatInput inp) {
       (inp == SMO_light_product_i_specular)) {
     dep |= (SSD_light | SSD_material);
   }
+  if ((inp == SMO_clipplane_x) ||
+      (inp == SMO_apiview_clipplane_i)) {
+    dep |= SSD_clip_planes;
+  }
 
   return dep;
 }
@@ -643,7 +649,7 @@ compile_parameter(const ShaderArgId        &arg_id,
     }
 
     bind._name = InternalName::get_root();
-    for (int i = 1; i < pieces.size(); ++i) {
+    for (size_t i = 1; i < pieces.size(); ++i) {
       bind._name = bind._name->append(pieces[i]);
     }
     _var_spec.push_back(bind);

+ 5 - 1
panda/src/gobj/shader.h

@@ -183,6 +183,9 @@ public:
     SMO_light_product_i_diffuse,
     SMO_light_product_i_specular,
 
+    // SMO_clipplane_x is world coords, GLSL needs eye coords
+    SMO_apiview_clipplane_i,
+
     SMO_INVALID
   };
 
@@ -261,6 +264,7 @@ public:
     SSD_shaderinputs  = 0x020,
     SSD_fog           = 0x040,
     SSD_light         = 0x080,
+    SSD_clip_planes   = 0x100,
   };
 
   enum ShaderBug {
@@ -307,7 +311,7 @@ public:
     void *_ptr;
     ShaderPtrType _type;
     bool _updated;
-    int _size; //number of elements vec3[4]=12
+    size_t _size; //number of elements vec3[4]=12
 
   public:
     INLINE ShaderPtrData();

+ 3 - 3
panda/src/gobj/texture.cxx

@@ -3325,7 +3325,7 @@ do_load_one(CData *cdata, const PfmFile &pfm, const string &name, int z, int n,
 ////////////////////////////////////////////////////////////////////
 bool Texture::
 do_load_sub_image(CData *cdata, const PNMImage &image, int x, int y, int z, int n) {
-  nassertr(n >= 0 && n < cdata->_ram_images.size(), false);
+  nassertr(n >= 0 && (size_t)n < cdata->_ram_images.size(), false);
 
   int tex_x_size = do_get_expected_mipmap_x_size(cdata, n);
   int tex_y_size = do_get_expected_mipmap_y_size(cdata, n);
@@ -4378,11 +4378,11 @@ do_make_ram_mipmap_image(CData *cdata, int n) {
   if (cdata->_has_clear_color) {
     // Fill the image with the clear color.
     unsigned char pixel[16];
-    const int pixel_size = do_get_clear_data(cdata, pixel);
+    const size_t pixel_size = (size_t)do_get_clear_data(cdata, pixel);
     nassertr(pixel_size > 0, cdata->_ram_images[n]._image);
 
     unsigned char *image_data = cdata->_ram_images[n]._image;
-    for (int i = 0; i < image_size; i += pixel_size) {
+    for (size_t i = 0; i < image_size; i += pixel_size) {
       memcpy(image_data + i, pixel, pixel_size);
     }
   }

+ 12 - 73
panda/src/gobj/textureCollection.cxx

@@ -49,79 +49,6 @@ operator = (const TextureCollection &copy) {
   _textures = copy._textures;
 }
 
-#ifdef HAVE_PYTHON
-////////////////////////////////////////////////////////////////////
-//     Function: TextureCollection::Constructor
-//       Access: Published
-//  Description: This special constructor accepts a Python list of
-//               Textures.  Since this constructor accepts a generic
-//               PyObject *, it should be the last constructor listed
-//               in the class record.
-////////////////////////////////////////////////////////////////////
-TextureCollection::
-TextureCollection(PyObject *self, PyObject *sequence) {
-  // We have to pre-initialize self's "this" pointer when we receive
-  // self in the constructor--the caller can't initialize this for us.
-  ((Dtool_PyInstDef *)self)->_ptr_to_object = this;
-
-  if (!PySequence_Check(sequence)) {
-    // If passed with a non-sequence, this isn't the right constructor.
-    PyErr_SetString(PyExc_TypeError, "TextureCollection constructor requires a sequence");
-    return;
-  }
-
-  int size = PySequence_Size(sequence);
-  for (int i = 0; i < size; ++i) {
-    PyObject *item = PySequence_GetItem(sequence, i);
-    if (item == NULL) {
-      return;
-    }
-    PyObject *result = PyObject_CallMethod(self, (char *)"add_texture", (char *)"O", item);
-    Py_DECREF(item);
-    if (result == NULL) {
-      // Unable to add item--probably it wasn't of the appropriate type.
-      ostringstream stream;
-      stream << "Element " << i << " in sequence passed to TextureCollection constructor could not be added";
-      string str = stream.str();
-      PyErr_SetString(PyExc_TypeError, str.c_str());
-      return;
-    }
-    Py_DECREF(result);
-  }
-}
-#endif  // HAVE_PYTHON
-
-#ifdef HAVE_PYTHON
-////////////////////////////////////////////////////////////////////
-//     Function: TextureCollection::__reduce__
-//       Access: Published
-//  Description: This special Python method is implement to provide
-//               support for the pickle module.
-////////////////////////////////////////////////////////////////////
-PyObject *TextureCollection::
-__reduce__(PyObject *self) const {
-  // Here we will return a 4-tuple: (Class, (args), None, iterator),
-  // where iterator is an iterator that will yield successive
-  // Textures.
-
-  // We should return at least a 2-tuple, (Class, (args)): the
-  // necessary class object whose constructor we should call
-  // (e.g. this), and the arguments necessary to reconstruct this
-  // object.
-
-  PyObject *this_class = PyObject_Type(self);
-  if (this_class == NULL) {
-    return NULL;
-  }
-
-  // Since a TextureCollection is itself an iterator, we can simply
-  // pass it as the fourth tuple component.
-  PyObject *result = Py_BuildValue("(O()OO)", this_class, Py_None, self);
-  Py_DECREF(this_class);
-  return result;
-}
-#endif  // HAVE_PYTHON
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureCollection::add_texture
 //       Access: Published
@@ -270,6 +197,18 @@ clear() {
   _textures.clear();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureCollection::reserve
+//       Access: Published
+//  Description: This is a hint to Panda to allocate enough memory
+//               to hold the given number of NodePaths, if you know
+//               ahead of time how many you will be adding.
+////////////////////////////////////////////////////////////////////
+void TextureCollection::
+reserve(size_t num) {
+  _textures.reserve(num);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureCollection::find_texture
 //       Access: Published

+ 3 - 4
panda/src/gobj/textureCollection.h

@@ -32,8 +32,8 @@ PUBLISHED:
   INLINE ~TextureCollection();
 
 #ifdef HAVE_PYTHON
-  TextureCollection(PyObject *self, PyObject *sequence);
-  PyObject *__reduce__(PyObject *self) const;
+  EXTENSION(TextureCollection(PyObject *self, PyObject *sequence));
+  EXTENSION(PyObject *__reduce__(PyObject *self) const);
 #endif
 
   void add_texture(Texture *texture);
@@ -43,6 +43,7 @@ PUBLISHED:
   void remove_duplicate_textures();
   bool has_texture(Texture *texture) const;
   void clear();
+  void reserve(size_t num);
 
   Texture *find_texture(const string &name) const;
 
@@ -74,5 +75,3 @@ INLINE ostream &operator << (ostream &out, const TextureCollection &col) {
 #include "textureCollection.I"
 
 #endif
-
-

+ 94 - 0
panda/src/gobj/textureCollection_ext.cxx

@@ -0,0 +1,94 @@
+// Filename: textureCollection_ext.cxx
+// Created by:  rdb (11Feb15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "textureCollection_ext.h"
+
+#ifdef HAVE_PYTHON
+
+#ifndef CPPPARSER
+extern struct Dtool_PyTypedObject Dtool_Texture;
+#endif
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureCollection::__init__
+//       Access: Published
+//  Description: This special constructor accepts a Python list of
+//               Textures.  Since this constructor accepts a generic
+//               PyObject *, it should be the last constructor listed
+//               in the class record.
+////////////////////////////////////////////////////////////////////
+void Extension<TextureCollection>::
+__init__(PyObject *self, PyObject *sequence) {
+  PyObject *fast = PySequence_Fast(sequence, "TextureCollection constructor requires a sequence");
+  if (fast == NULL) {
+    return;
+  }
+
+  Py_ssize_t size = PySequence_Fast_GET_SIZE(fast);
+  _this->reserve(size);
+
+  for (int i = 0; i < size; ++i) {
+    PyObject *item = PySequence_Fast_GET_ITEM(fast, i);
+    if (item == NULL) {
+      return;
+    }
+
+    Texture *tex;
+    DTOOL_Call_ExtractThisPointerForType(item, &Dtool_Texture, (void **)&tex);
+    if (tex == (Texture *)NULL) {
+      // Unable to add item--probably it wasn't of the appropriate type.
+      ostringstream stream;
+      stream << "Element " << i << " in sequence passed to TextureCollection constructor is not a Texture";
+      string str = stream.str();
+      PyErr_SetString(PyExc_TypeError, str.c_str());
+      Py_DECREF(fast);
+      return;
+    } else {
+      _this->add_texture(tex);
+    }
+  }
+
+  Py_DECREF(fast);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureCollection::__reduce__
+//       Access: Published
+//  Description: This special Python method is implement to provide
+//               support for the pickle module.
+////////////////////////////////////////////////////////////////////
+PyObject *Extension<TextureCollection>::
+__reduce__(PyObject *self) const {
+  // Here we will return a 4-tuple: (Class, (args), None, iterator),
+  // where iterator is an iterator that will yield successive
+  // Textures.
+
+  // We should return at least a 2-tuple, (Class, (args)): the
+  // necessary class object whose constructor we should call
+  // (e.g. this), and the arguments necessary to reconstruct this
+  // object.
+
+  PyObject *this_class = PyObject_Type(self);
+  if (this_class == NULL) {
+    return NULL;
+  }
+
+  // Since a TextureCollection is itself an iterator, we can simply
+  // pass it as the fourth tuple component.
+  PyObject *result = Py_BuildValue("(O()OO)", this_class, Py_None, self);
+  Py_DECREF(this_class);
+  return result;
+}
+
+#endif  // HAVE_PYTHON

+ 42 - 0
panda/src/gobj/textureCollection_ext.h

@@ -0,0 +1,42 @@
+// Filename: textureCollection_ext.h
+// Created by:  rdb (11Feb15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef TEXTURECOLLECTION_EXT_H
+#define TEXTURECOLLECTION_EXT_H
+
+#include "dtoolbase.h"
+
+#ifdef HAVE_PYTHON
+
+#include "extension.h"
+#include "textureCollection.h"
+#include "py_panda.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : Extension<TextureCollection>
+// Description : This class defines the extension methods for
+//               TextureCollection, which are called instead of
+//               any C++ methods with the same prototype.
+////////////////////////////////////////////////////////////////////
+template<>
+class Extension<TextureCollection> : public ExtensionBase<TextureCollection> {
+public:
+  void __init__(PyObject *self, PyObject *sequence);
+
+  PyObject *__reduce__(PyObject *self) const;
+};
+
+#endif  // HAVE_PYTHON
+
+#endif  // TEXTURECOLLECTION_EXT_H

+ 1 - 1
panda/src/gobj/transformBlend.cxx

@@ -109,7 +109,7 @@ limit_transforms(int max_transforms) {
     return;
   }
 
-  while (_entries.size() > max_transforms) {
+  while ((int)_entries.size() > max_transforms) {
     // Repeatedly find and remove the least-important transform.
     nassertv(!_entries.empty());
     Entries::iterator ei_least = _entries.begin();

+ 3 - 3
panda/src/gobj/vertexDataPage.h

@@ -114,7 +114,7 @@ private:
   typedef pdeque<VertexDataPage *> PendingPages;
 
   class PageThreadManager;
-  class PageThread : public Thread {
+  class EXPCL_PANDA_GOBJ PageThread : public Thread {
   public:
     PageThread(PageThreadManager *manager, const string &name);
 
@@ -132,7 +132,7 @@ private:
   };
   typedef pvector<PT(PageThread) > PageThreads;
 
-  class PageThreadManager : public ReferenceCount {
+  class EXPCL_PANDA_GOBJ PageThreadManager : public ReferenceCount {
   public:
     PageThreadManager(int num_threads);
     void add_page(VertexDataPage *page, RamClass ram_class);
@@ -176,7 +176,7 @@ private:
 
   // We build up a temporary linked list of these while deflating
   // (compressing) the vertex data in-memory.
-  class DeflatePage {
+  class EXPCL_PANDA_GOBJ DeflatePage {
   public:
     DeflatePage() {
       _used_size = 0;

+ 3 - 1
panda/src/gobj/vertexDataSaveFile.h

@@ -21,7 +21,9 @@
 #include "pmutex.h"
 
 #if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 #endif
 

+ 6 - 6
panda/src/linmath/lpoint2_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -47,6 +41,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint2)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {

+ 6 - 6
panda/src/linmath/lpoint3_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -48,6 +42,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint3)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {

+ 6 - 6
panda/src/linmath/lpoint4_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -49,6 +43,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint4)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {

+ 6 - 7
panda/src/linmath/lvecBase2_ext_src.I

@@ -12,13 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PYNUMBER_FLOATTYPE PyNumber_Long
@@ -86,6 +79,12 @@ __reduce__(PyObject *self) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase2)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {

+ 6 - 7
panda/src/linmath/lvecBase3_ext_src.I

@@ -12,13 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PYNUMBER_FLOATTYPE PyNumber_Long
@@ -87,6 +80,12 @@ __reduce__(PyObject *self) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase3)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {

+ 6 - 7
panda/src/linmath/lvecBase4_ext_src.I

@@ -12,13 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PYNUMBER_FLOATTYPE PyNumber_Long
@@ -88,6 +81,12 @@ __reduce__(PyObject *self) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase4)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {

+ 6 - 6
panda/src/linmath/lvector2_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -47,6 +41,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector2)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {

+ 6 - 6
panda/src/linmath/lvector3_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -48,6 +42,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector3)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {

+ 6 - 6
panda/src/linmath/lvector4_ext_src.I

@@ -12,12 +12,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef CPPPARSER
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
-IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
-#endif
-
 #ifdef FLOATTYPE_IS_INT
 #if PY_MAJOR_VERSION >= 3
 #define PY_FROM_FLOATTYPE PyLong_FromLong
@@ -49,6 +43,12 @@ python_repr(ostream &out, const string &class_name) const {
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector4)>::
 __getattr__(const string &attr_name) const {
+#ifndef CPPPARSER
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
+  extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector4);
+#endif
+
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {

+ 2 - 0
panda/src/mathutil/config_mathutil.N

@@ -66,3 +66,5 @@ forcetype PointerToBase<ReferenceCountedVector<LVecBase2i> >
 forcetype PointerToArrayBase<LVecBase2i>
 forcetype PointerToArray<LVecBase2i>
 forcetype ConstPointerToArray<LVecBase2i>
+
+forceinclude "pointerToArray_ext.h"

+ 1 - 1
panda/src/mathutil/triangulator.cxx

@@ -287,7 +287,7 @@ cleanup_polygon_indices(vector_int &polygon) {
   // First, check for index bounds.
   size_t pi = 0;
   while (pi < polygon.size()) {
-    if (polygon[pi] >= 0 && polygon[pi] < _vertices.size()) {
+    if (polygon[pi] >= 0 && (size_t)polygon[pi] < _vertices.size()) {
       // This vertex is OK.
       ++pi;
     } else {

+ 21 - 21
panda/src/movies/microphoneAudioDS.cxx

@@ -22,7 +22,9 @@
 
 #ifdef HAVE_DIRECTCAM
 
-#define WIN32_LEAN_AND_MEAN 
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
 
 #undef Configure
 
@@ -33,9 +35,7 @@
 //       Class : MicrophoneAudioDS
 // Description : The directshow implementation of microphones.
 ////////////////////////////////////////////////////////////////////
-
-class MicrophoneAudioDS : public MicrophoneAudio
-{
+class MicrophoneAudioDS : public MicrophoneAudio {
 public:
   static void find_all_microphones_ds();
   friend void find_all_microphones_ds();
@@ -56,7 +56,7 @@ private:
   typedef pvector <AudioBuf> AudioBuffers;
 
   static void delete_buffers(AudioBuffers &buffers);
-  
+
   friend class MicrophoneAudioCursorDS;
 
 public:
@@ -90,7 +90,7 @@ public:
   typedef MicrophoneAudioDS::AudioBuffers AudioBuffers;
   MicrophoneAudioCursorDS(MicrophoneAudioDS *src, AudioBuffers &bufs, HWAVEIN hwav);
   virtual ~MicrophoneAudioCursorDS();
-  
+
   AudioBuffers _buffers;
   HWAVEIN _hwavein;
   int _samples_per_buffer;
@@ -105,7 +105,7 @@ public:
   HWAVEIN _handle;
   int     _next;    // Which buffer is the next one to read from.
   int     _offset;  // How many samples to skip in the buffer.
-  
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
@@ -129,7 +129,7 @@ TypeHandle MicrophoneAudioCursorDS::_type_handle;
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioDS::find_all_microphones_ds
 //       Access: Public, Static
-//  Description: Finds all DirectShow microphones and adds them to 
+//  Description: Finds all DirectShow microphones and adds them to
 //               the global list _all_microphones.
 ////////////////////////////////////////////////////////////////////
 void MicrophoneAudioDS::
@@ -205,7 +205,7 @@ delete_buffers(AudioBuffers &buffers) {
 ////////////////////////////////////////////////////////////////////
 PT(MovieAudioCursor) MicrophoneAudioDS::
 open() {
-  
+
   // Allocate the buffers. 64 buffers, not quite 1/20 sec each.
   int samples;
   switch (_rate) {
@@ -248,7 +248,7 @@ open() {
     nassert_raise("Could not allocate audio input buffers.");
     return NULL;
   }
-  
+
   WAVEFORMATEX format;
   format.wFormatTag = WAVE_FORMAT_PCM;
   format.nChannels = _channels;
@@ -260,7 +260,7 @@ open() {
 
   HWAVEIN hwav;
   MMRESULT stat = waveInOpen(&hwav, _device_id, &format, NULL, NULL, CALLBACK_NULL);
-  
+
   if (stat != MMSYSERR_NOERROR) {
     delete_buffers(buffers);
     nassert_raise("Could not open audio input device.");
@@ -284,7 +284,7 @@ open() {
     waveInClose(hwav);
     delete_buffers(buffers);
     nassert_raise("Could not start recording on input device.");
-    return NULL;    
+    return NULL;
   }
   return new MicrophoneAudioCursorDS(this, buffers, hwav);
 }
@@ -292,7 +292,7 @@ open() {
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioCursorDS::Constructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 MicrophoneAudioCursorDS::
 MicrophoneAudioCursorDS(MicrophoneAudioDS *src, AudioBuffers &bufs, HWAVEIN hwav) :
@@ -314,7 +314,7 @@ MicrophoneAudioCursorDS(MicrophoneAudioDS *src, AudioBuffers &bufs, HWAVEIN hwav
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioCursorDS::cleanup
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void MicrophoneAudioCursorDS::
 cleanup() {
@@ -330,7 +330,7 @@ cleanup() {
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioCursorDS::Destructor
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 MicrophoneAudioCursorDS::
 ~MicrophoneAudioCursorDS() {
@@ -340,7 +340,7 @@ MicrophoneAudioCursorDS::
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioCursorDS::read_samples
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void MicrophoneAudioCursorDS::
 read_samples(int n, PN_int16 *data) {
@@ -351,19 +351,19 @@ read_samples(int n, PN_int16 *data) {
       if ((_buffers[index]._header->dwFlags & WHDR_DONE)==0) {
         break;
       }
-      
+
       // Find start of data in buffer.
       PN_int16 *src = (PN_int16*)(_buffers[index]._storage);
       src += (_offset * _audio_channels);
-      
+
       // Decide how many samples to extract from this buffer.
       int samples = _samples_per_buffer;
       samples -= _offset;
       if (samples > n) samples = n;
-      
+
       // Copy data to output buffer.
       memcpy(data, src, samples * 2 * _audio_channels);
-      
+
       // Advance pointers.
       data += samples * _audio_channels;
       n -= samples;
@@ -397,7 +397,7 @@ read_samples(int n, PN_int16 *data) {
 ////////////////////////////////////////////////////////////////////
 //     Function: MicrophoneAudioCursorDS::ready
 //       Access: Published
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 int MicrophoneAudioCursorDS::
 ready() const {

+ 5 - 1
panda/src/nativenet/buffered_datagramconnection.h

@@ -11,6 +11,7 @@
 //  3. Handle Framing and Unframing properly ..
 //
 ////////////////////////////////////////////////////////////////////
+
 #include "pandabase.h"
 #include "socket_base.h"
 #include "datagram.h"
@@ -19,9 +20,12 @@
 #include "buffered_datagramwriter.h"
 #include "config_nativenet.h"
 
+#ifdef HAVE_PYTHON
+#include "py_panda.h"
+#endif
 
 ////////////////////////////////////////////////////////////////
-// there are 3 states   
+// there are 3 states
 //
 //      1. Socket not even assigned,,,,
 //      2. Socket Assigned and trying to get a active connect open

+ 1 - 1
panda/src/net/connectionManager.h

@@ -67,7 +67,7 @@ PUBLISHED:
 
   static string get_host_name();
 
-  class Interface {
+  class EXPCL_PANDA_NET Interface {
   PUBLISHED:
     const string &get_name() const { return _name; }
     const string &get_mac_address() const { return _mac_address; }

+ 13 - 13
panda/src/ode/odeGeom_ext.cxx

@@ -31,19 +31,19 @@
 #ifdef HAVE_PYTHON
 
 #ifndef CPPPARSER
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeBoxGeom;
-//extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeConvexGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeHashSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeCappedCylinderGeom;
-//extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeHeightfieldGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdePlaneGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeQuadTreeSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeRayGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSimpleSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSphereGeom;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeTriMeshGeom;
+extern Dtool_PyTypedObject Dtool_OdeBoxGeom;
+//extern Dtool_PyTypedObject Dtool_OdeConvexGeom;
+extern Dtool_PyTypedObject Dtool_OdeGeom;
+extern Dtool_PyTypedObject Dtool_OdeHashSpace;
+extern Dtool_PyTypedObject Dtool_OdeCappedCylinderGeom;
+//extern Dtool_PyTypedObject Dtool_OdeHeightfieldGeom;
+extern Dtool_PyTypedObject Dtool_OdePlaneGeom;
+extern Dtool_PyTypedObject Dtool_OdeQuadTreeSpace;
+extern Dtool_PyTypedObject Dtool_OdeRayGeom;
+extern Dtool_PyTypedObject Dtool_OdeSimpleSpace;
+extern Dtool_PyTypedObject Dtool_OdeSpace;
+extern Dtool_PyTypedObject Dtool_OdeSphereGeom;
+extern Dtool_PyTypedObject Dtool_OdeTriMeshGeom;
 #endif
 
 ////////////////////////////////////////////////////////////////////

+ 12 - 12
panda/src/ode/odeJoint_ext.cxx

@@ -30,18 +30,18 @@
 #include "odePlane2dJoint.h"
 
 #ifndef CPPPARSER
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeBallJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeHingeJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSliderJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeContactJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeUniversalJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeHinge2Joint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeFixedJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeNullJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeAMotorJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeLMotorJoint;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdePlane2dJoint;
+extern Dtool_PyTypedObject Dtool_OdeJoint;
+extern Dtool_PyTypedObject Dtool_OdeBallJoint;
+extern Dtool_PyTypedObject Dtool_OdeHingeJoint;
+extern Dtool_PyTypedObject Dtool_OdeSliderJoint;
+extern Dtool_PyTypedObject Dtool_OdeContactJoint;
+extern Dtool_PyTypedObject Dtool_OdeUniversalJoint;
+extern Dtool_PyTypedObject Dtool_OdeHinge2Joint;
+extern Dtool_PyTypedObject Dtool_OdeFixedJoint;
+extern Dtool_PyTypedObject Dtool_OdeNullJoint;
+extern Dtool_PyTypedObject Dtool_OdeAMotorJoint;
+extern Dtool_PyTypedObject Dtool_OdeLMotorJoint;
+extern Dtool_PyTypedObject Dtool_OdePlane2dJoint;
 #endif
 
 ////////////////////////////////////////////////////////////////////

+ 4 - 4
panda/src/ode/odeSpace_ext.cxx

@@ -24,10 +24,10 @@
 #include "odeQuadTreeSpace.h"
 
 #ifndef CPPPARSER
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeHashSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSimpleSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeSpace;
-extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeQuadTreeSpace;
+extern Dtool_PyTypedObject Dtool_OdeHashSpace;
+extern Dtool_PyTypedObject Dtool_OdeSimpleSpace;
+extern Dtool_PyTypedObject Dtool_OdeSpace;
+extern Dtool_PyTypedObject Dtool_OdeQuadTreeSpace;
 #endif
 
 PyObject *Extension<OdeSpace>::_python_callback = NULL;

+ 11 - 9
panda/src/ode/odeTriMeshData.h

@@ -28,9 +28,11 @@
 #include "geomTriangles.h"
 #include "geomTristrips.h"
 
+#include "config_ode.h"
+
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeTriMeshData
-// Description : 
+// Description :
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeTriMeshData : public TypedReferenceCount {
 public:
@@ -54,7 +56,7 @@ PUBLISHED:
   virtual ~OdeTriMeshData();
 
   void destroy();
-  
+
   // INLINE void set(int data_id, void* in_data);
   // INLINE void* get(int data_id);
   // INLINE void get_buffer(unsigned char** buf, int* buf_len) const;
@@ -63,7 +65,7 @@ PUBLISHED:
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
   void write_faces(ostream &out) const;
 
-public: 
+public:
   INLINE void build_single(const void* vertices, int vertex_stride, int vertex_count, \
                            const void* indices, int index_count, int tri_stride);
   INLINE void build_single1(const void* vertices, int vertex_stride, int vertex_count, \
@@ -96,7 +98,7 @@ private:
   void process_model(const NodePath& model, bool &use_normals);
   void process_geom_node(const GeomNode *geomNode);
   void process_geom(const Geom *geom);
-  void process_primitive(const GeomPrimitive *primitive, 
+  void process_primitive(const GeomPrimitive *primitive,
                          CPT(GeomVertexData) vData);
   void analyze(const GeomNode *geomNode);
   void analyze(const Geom *geom);
@@ -104,15 +106,15 @@ private:
 
   OdeTriMeshData(const OdeTriMeshData &other);
   void operator = (const OdeTriMeshData &other);
-  
+
 protected:
-  struct StridedVertex{
+  struct StridedVertex {
     dReal Vertex[3];
-  };  
-  struct StridedTri{
+  };
+  struct StridedTri {
     int Indices[3];
   };
-  struct FaceNormal{
+  struct FaceNormal {
     dVector3 Normal;
   };
 

+ 1 - 1
panda/src/parametrics/curveFitter.h

@@ -32,7 +32,7 @@ class NurbsCurve;
 //       Class : CurveFitter
 // Description :
 ////////////////////////////////////////////////////////////////////
-class CurveFitter {
+class EXPCL_PANDA_GOBJ CurveFitter {
 PUBLISHED:
   CurveFitter();
   ~CurveFitter();

Some files were not shown because too many files changed in this diff