Browse Source

Merge branch 'master' into cmake

Sam Edwards 7 years ago
parent
commit
6b26889e7e
100 changed files with 1434 additions and 3472 deletions
  1. 1 1
      contrib/src/rplight/gpuCommand.I
  2. 1 1
      direct/src/plugin/fileSpec.cxx
  3. 1 1
      direct/src/plugin/get_twirl_data.cxx
  4. 1 1
      direct/src/plugin/load_plugin.cxx
  5. 3 3
      direct/src/plugin/p3dCert.h
  6. 2 2
      direct/src/plugin/p3dCert_wx.cxx
  7. 4 4
      direct/src/plugin/p3dCert_wx.h
  8. 1 1
      direct/src/plugin/p3dHost.cxx
  9. 3 3
      direct/src/plugin/p3dInstanceManager.h
  10. 1 1
      direct/src/plugin/p3dPackage.cxx
  11. 3 3
      direct/src/plugin_activex/P3DActiveX.cpp
  12. 3 3
      direct/src/plugin_activex/P3DActiveXCtrl.cpp
  13. 1 1
      direct/src/plugin_activex/P3DActiveXCtrl.h
  14. 1 1
      direct/src/plugin_activex/PPInstance.h
  15. 1 1
      direct/src/plugin_activex/PPInterface.cpp
  16. 2 1
      direct/src/plugin_activex/PPLogger.cpp
  17. 1 1
      direct/src/plugin_npapi/nppanda3d_common.h
  18. 4 4
      direct/src/showutil/FreezeTool.py
  19. 1 1
      dtool/metalibs/dtoolconfig/pydtool.cxx
  20. 0 2
      dtool/src/dtoolbase/dtoolbase.h
  21. 15 0
      dtool/src/dtoolbase/typeHandle.cxx
  22. 4 0
      dtool/src/dtoolbase/typeHandle.h
  23. 2 1
      dtool/src/dtoolbase/typeHandle_ext.cxx
  24. 18 0
      dtool/src/dtoolbase/typeRegistry.cxx
  25. 3 0
      dtool/src/dtoolbase/typeRegistry.h
  26. 13 0
      dtool/src/dtoolbase/typeRegistryNode.I
  27. 23 0
      dtool/src/dtoolbase/typeRegistryNode.cxx
  28. 5 0
      dtool/src/dtoolbase/typeRegistryNode.h
  29. 7 2
      dtool/src/interrogate/functionRemap.cxx
  30. 150 48
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  31. 2 2
      dtool/src/interrogate/interfaceMakerPythonNative.h
  32. 0 3
      dtool/src/interrogate/interrogate.cxx
  33. 9 14
      dtool/src/interrogate/interrogate_module.cxx
  34. 0 3
      dtool/src/interrogate/parse_file.cxx
  35. 103 91
      dtool/src/interrogatedb/dtool_super_base.cxx
  36. 0 1
      dtool/src/interrogatedb/p3interrogatedb_composite1.cxx
  37. 0 3
      dtool/src/interrogatedb/p3interrogatedb_composite2.cxx
  38. 0 7
      dtool/src/interrogatedb/py_compat.cxx
  39. 2 9
      dtool/src/interrogatedb/py_compat.h
  40. 17 12
      dtool/src/interrogatedb/py_panda.I
  41. 48 174
      dtool/src/interrogatedb/py_panda.cxx
  42. 43 54
      dtool/src/interrogatedb/py_panda.h
  43. 299 674
      dtool/src/interrogatedb/py_wrappers.cxx
  44. 6 23
      dtool/src/interrogatedb/py_wrappers.h
  45. 0 3
      dtool/src/parser-inc/Python.h
  46. 1 1
      dtool/src/prc/configPage.cxx
  47. 2 2
      dtool/src/prc/encryptStreamBuf.cxx
  48. 2 2
      dtool/src/prc/prcKeyRegistry.cxx
  49. 5 5
      dtool/src/prckeys/makePrcKey.cxx
  50. 5 5
      dtool/src/prckeys/signPrcFile_src.cxx
  51. 8 0
      dtool/src/pystub/pystub.cxx
  52. 0 3
      dtool/src/test_interrogate/test_interrogate.cxx
  53. 39 14
      makepanda/installer.nsi
  54. 6 1
      makepanda/installpanda.py
  55. 209 259
      makepanda/makepanda.py
  56. 151 28
      makepanda/makepandacore.py
  57. 1 1
      makepanda/makewheel.py
  58. 5 0
      makepanda/test_wheel.py
  59. 2 1
      panda/src/android/android_main.cxx
  60. 1 1
      panda/src/audiotraits/fmodAudioSound.cxx
  61. 2 2
      panda/src/audiotraits/fmodAudioSound.h
  62. 2 1
      panda/src/audiotraits/globalMilesManager.h
  63. 2 1
      panda/src/audiotraits/milesAudioManager.h
  64. 2 1
      panda/src/audiotraits/milesAudioSample.h
  65. 2 1
      panda/src/audiotraits/milesAudioSequence.h
  66. 2 1
      panda/src/audiotraits/milesAudioSound.h
  67. 2 1
      panda/src/audiotraits/milesAudioStream.h
  68. 16 0
      panda/src/audiotraits/openalAudioManager.cxx
  69. 2 1
      panda/src/awesomium/awWebCore.cxx
  70. 3 3
      panda/src/awesomium/awesomium_includes.h
  71. 15 15
      panda/src/bullet/bullet_includes.h
  72. 5 0
      panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm
  73. 0 93
      panda/src/collada/colladaBindMaterial.cxx
  74. 0 41
      panda/src/collada/colladaBindMaterial.h
  75. 0 28
      panda/src/collada/colladaInput.I
  76. 0 265
      panda/src/collada/colladaInput.cxx
  77. 0 77
      panda/src/collada/colladaInput.h
  78. 0 12
      panda/src/collada/colladaLoader.I
  79. 0 549
      panda/src/collada/colladaLoader.cxx
  80. 0 76
      panda/src/collada/colladaLoader.h
  81. 0 40
      panda/src/collada/colladaPrimitive.I
  82. 0 293
      panda/src/collada/colladaPrimitive.cxx
  83. 0 71
      panda/src/collada/colladaPrimitive.h
  84. 0 87
      panda/src/collada/config_collada.cxx
  85. 0 36
      panda/src/collada/config_collada.h
  86. 0 92
      panda/src/collada/load_collada_file.cxx
  87. 0 36
      panda/src/collada/load_collada_file.h
  88. 0 74
      panda/src/collada/loaderFileTypeDae.cxx
  89. 0 54
      panda/src/collada/loaderFileTypeDae.h
  90. 0 3
      panda/src/collada/p3collada_composite1.cxx
  91. 0 28
      panda/src/collada/pre_collada_include.h
  92. 1 1
      panda/src/device/clientBase.h
  93. 4 0
      panda/src/display/p3display_ext_composite.cxx
  94. 2 0
      panda/src/display/windowProperties.cxx
  95. 7 2
      panda/src/display/windowProperties.h
  96. 82 0
      panda/src/display/windowProperties_ext.cxx
  97. 37 0
      panda/src/display/windowProperties_ext.h
  98. 1 1
      panda/src/downloader/bioPtr.cxx
  99. 2 1
      panda/src/downloader/httpCookie.cxx
  100. 2 2
      panda/src/downloader/httpDigestAuthorization.cxx

+ 1 - 1
contrib/src/rplight/gpuCommand.I

@@ -24,7 +24,7 @@
  *
  */
 
-#include "stdint.h"
+#include <stdint.h>
 
 /**
  * @brief Appends an integer to the GPUCommand.

+ 1 - 1
direct/src/plugin/fileSpec.cxx

@@ -13,7 +13,7 @@
 
 #include "fileSpec.h"
 #include "wstring_encode.h"
-#include "openssl/md5.h"
+#include <openssl/md5.h>
 
 #include <fstream>
 #include <fcntl.h>

+ 1 - 1
direct/src/plugin/get_twirl_data.cxx

@@ -12,7 +12,7 @@
  */
 
 #include "get_twirl_data.h"
-#include "string.h"
+#include <string.h>
 
 struct twirl_flip {
   int _index;

+ 1 - 1
direct/src/plugin/load_plugin.cxx

@@ -16,7 +16,7 @@
 #include "is_pathsep.h"
 #include "wstring_encode.h"
 
-#include "assert.h"
+#include <assert.h>
 
 #include <iostream>
 

+ 3 - 3
direct/src/plugin/p3dCert.h

@@ -18,9 +18,9 @@
 #include <FL/Fl_Window.H>
 
 #define OPENSSL_NO_KRB5
-#include "openssl/x509.h"
-#include "openssl/x509_vfy.h"
-#include "openssl/pem.h"
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/pem.h>
 
 #include <string>
 #include <iostream>

+ 2 - 2
direct/src/plugin/p3dCert_wx.cxx

@@ -15,8 +15,8 @@
 #include "wstring_encode.h"
 #include "mkdir_complete.h"
 
-#include "wx/cmdline.h"
-#include "wx/filename.h"
+#include <wx/cmdline.h>
+#include <wx/filename.h>
 
 #include "ca_bundle_data_src.c"
 

+ 4 - 4
direct/src/plugin/p3dCert_wx.h

@@ -14,12 +14,12 @@
 #ifndef P3DCERT_WX_H
 #define P3DCERT_WX_H
 
-#include "wx/wx.h"
+#include <wx/wx.h>
 
 #define OPENSSL_NO_KRB5
-#include "openssl/x509.h"
-#include "openssl/x509_vfy.h"
-#include "openssl/pem.h"
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/pem.h>
 
 #include <string>
 #include <iostream>

+ 1 - 1
direct/src/plugin/p3dHost.cxx

@@ -17,7 +17,7 @@
 #include "mkdir_complete.h"
 #include "wstring_encode.h"
 #include "xml_helpers.h"
-#include "openssl/md5.h"
+#include <openssl/md5.h>
 
 #include <algorithm>
 

+ 3 - 3
direct/src/plugin/p3dInstanceManager.h

@@ -26,9 +26,9 @@
 #endif
 
 #define OPENSSL_NO_KRB5
-#include "openssl/x509.h"
-#include "openssl/pem.h"
-#include "openssl/md5.h"
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/md5.h>
 
 class P3DInstance;
 class P3DSession;

+ 1 - 1
direct/src/plugin/p3dPackage.cxx

@@ -20,7 +20,7 @@
 #include "mkdir_complete.h"
 #include "wstring_encode.h"
 
-#include "zlib.h"
+#include <zlib.h>
 
 #include <algorithm>
 #include <fstream>

+ 3 - 3
direct/src/plugin_activex/P3DActiveX.cpp

@@ -16,9 +16,9 @@
 #include "stdafx.h"
 #include "P3DActiveX.h"
 
-#include "comcat.h"
-#include "strsafe.h"
-#include "objsafe.h"
+#include <comcat.h>
+#include <strsafe.h>
+#include <objsafe.h>
 
 
 #ifdef _DEBUG

+ 3 - 3
direct/src/plugin_activex/P3DActiveXCtrl.cpp

@@ -20,9 +20,9 @@
 #include "P3DActiveXPropPage.h"
 #include "PPBrowserObject.h"
 
-#include "Mshtml.h"
-#include "atlconv.h"
-#include "comutil.h"
+#include <Mshtml.h>
+#include <atlconv.h>
+#include <comutil.h>
 
 #include <strstream>
 

+ 1 - 1
direct/src/plugin_activex/P3DActiveXCtrl.h

@@ -19,7 +19,7 @@
 #include "PPPandaObject.h"
 #include "PPInterface.h"
 #include "get_twirl_data.h"
-#include "Mshtml.h"
+#include <Mshtml.h>
 
 #include <vector>
 

+ 1 - 1
direct/src/plugin_activex/PPInstance.h

@@ -16,7 +16,7 @@
 #include <string>
 #include <vector>
 #include <math.h>
-#include "afxmt.h"
+#include <afxmt.h>
 
 #include "p3d_plugin.h"
 #include "PPDownloadCallback.h"

+ 1 - 1
direct/src/plugin_activex/PPInterface.cpp

@@ -20,7 +20,7 @@
 #include "P3DActiveXCtrl.h"
 
 #include <strstream>
-#include "Mshtml.h"
+#include <Mshtml.h>
 
 PPInterface::PPInterface( )
 {

+ 2 - 1
direct/src/plugin_activex/PPLogger.cpp

@@ -13,11 +13,12 @@
 
 #include "stdafx.h"
 
-#include "windows.h"
 #include "PPLogger.h"
 #include "mkdir_complete.h"
 #include "wstring_encode.h"
 
+#include <windows.h>
+
 std::ofstream PPLogger::m_logfile;
 bool PPLogger::m_isOpen = false;
 

+ 1 - 1
direct/src/plugin_npapi/nppanda3d_common.h

@@ -64,7 +64,7 @@ extern bool has_plugin_thread_async_call;
 
 #include "npapi.h"
 #if NP_VERSION_MAJOR == 0 && NP_VERSION_MINOR <= 19
-  #include "npupp.h"
+  #include <npupp.h>
 #else
   // Somewhere between version 0.19 and 0.22, Mozilla renamed npupp.h to
   // npfunctions.h.

+ 4 - 4
direct/src/showutil/FreezeTool.py

@@ -246,7 +246,7 @@ class CompilationEnvironment:
 frozenMainCode = """
 /* Python interpreter main program for frozen scripts */
 
-#include "Python.h"
+#include <Python.h>
 
 #if PY_MAJOR_VERSION >= 3
 #include <locale.h>
@@ -386,7 +386,7 @@ error:
 # The code from frozen_dllmain.c in the Python source repository.
 # Windows only.
 frozenDllMainCode = """
-#include "windows.h"
+#include <windows.h>
 
 static char *possibleModules[] = {
     "pywintypes",
@@ -555,9 +555,9 @@ static PyMethodDef nullMethods[] = {
 """
 
 programFile = """
-#include "Python.h"
+#include <Python.h>
 #ifdef _WIN32
-#include "malloc.h"
+#include <malloc.h>
 #endif
 
 %(moduleDefs)s

+ 1 - 1
dtool/metalibs/dtoolconfig/pydtool.cxx

@@ -17,7 +17,7 @@
 #if PYTHON_FRAMEWORK
   #include <Python/Python.h>
 #else
-  #include "Python.h"
+  #include <Python.h>
 #endif
 
 static PyObject *_inP07yttbRf(PyObject *self, PyObject *args);

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

@@ -138,12 +138,10 @@
 #endif
 #endif
 
-#ifdef HAVE_PYTHON
 // Instead of including the Python headers, which will implicitly add a linker
 // flag to link in Python, we'll just excerpt the forward declaration of
 // PyObject.
 typedef struct _object PyObject;
-#endif
 
 #ifndef HAVE_EIGEN
 // If we don't have the Eigen library, don't define LINMATH_ALIGN.

+ 15 - 0
dtool/src/dtoolbase/typeHandle.cxx

@@ -153,6 +153,21 @@ deallocate_array(void *ptr) {
   PANDA_FREE_ARRAY(ptr);
 }
 
+#ifdef HAVE_PYTHON
+/**
+ * Returns the internal void pointer that is stored for interrogate's benefit.
+ */
+PyObject *TypeHandle::
+get_python_type() const {
+  TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr);
+  if (rnode != nullptr) {
+    return rnode->get_python_type();
+  } else {
+    return nullptr;
+  }
+}
+#endif
+
 /**
  * Return the Index of the BEst fit Classs from a set
  */

+ 4 - 0
dtool/src/dtoolbase/typeHandle.h

@@ -138,6 +138,10 @@ PUBLISHED:
   MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class);
 
 public:
+#ifdef HAVE_PYTHON
+  PyObject *get_python_type() const;
+#endif
+
   void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
   void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
   void deallocate_array(void *ptr);

+ 2 - 1
dtool/src/dtoolbase/typeHandle_ext.cxx

@@ -22,7 +22,8 @@
  */
 TypeHandle Extension<TypeHandle>::
 make(PyTypeObject *tp) {
-  if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) {
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) {
     PyErr_SetString(PyExc_TypeError, "a Panda type is required");
     return TypeHandle::none();
   }

+ 18 - 0
dtool/src/dtoolbase/typeRegistry.cxx

@@ -207,6 +207,24 @@ record_alternate_name(TypeHandle type, const string &name) {
   _lock->unlock();
 }
 
+#ifdef HAVE_PYTHON
+/**
+ * Records the given Python type pointer in the type registry for the benefit
+ * of interrogate.
+ */
+void TypeRegistry::
+record_python_type(TypeHandle type, PyObject *python_type) {
+  _lock->lock();
+
+  TypeRegistryNode *rnode = look_up(type, nullptr);
+  if (rnode != nullptr) {
+    rnode->_python_type = python_type;
+  }
+
+  _lock->unlock();
+}
+#endif
+
 /**
  * Looks for a previously-registered type of the given name.  Returns its
  * TypeHandle if it exists, or TypeHandle::none() if there is no such type.

+ 3 - 0
dtool/src/dtoolbase/typeRegistry.h

@@ -45,6 +45,9 @@ PUBLISHED:
 
   void record_derivation(TypeHandle child, TypeHandle parent);
   void record_alternate_name(TypeHandle type, const std::string &name);
+#ifdef HAVE_PYTHON
+  void record_python_type(TypeHandle type, PyObject *python_type);
+#endif
 
   TypeHandle find_type(const std::string &name) const;
   TypeHandle find_type_by_id(int id) const;

+ 13 - 0
dtool/src/dtoolbase/typeRegistryNode.I

@@ -11,6 +11,19 @@
  * @date 2001-08-06
  */
 
+/**
+ * Returns the Python type object associated with this node.
+ */
+INLINE PyObject *TypeRegistryNode::
+get_python_type() const {
+  if (_python_type != nullptr || _parent_classes.empty()) {
+    return _python_type;
+  } else {
+    // Recurse through parent classes.
+    return r_get_python_type();
+  }
+}
+
 /**
  *
  */

+ 23 - 0
dtool/src/dtoolbase/typeRegistryNode.cxx

@@ -308,6 +308,29 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count,
   }
 }
 
+/**
+ * Recurses through the parent nodes to find the best Python type object to
+ * represent objects of this type.
+ */
+PyObject *TypeRegistryNode::
+r_get_python_type() const {
+  Classes::const_iterator ni;
+  for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) {
+    const TypeRegistryNode *parent = *ni;
+    if (parent->_python_type != nullptr) {
+      return parent->_python_type;
+
+    } else if (!parent->_parent_classes.empty()) {
+      PyObject *py_type = parent->r_get_python_type();
+      if (py_type != nullptr) {
+        return py_type;
+      }
+    }
+  }
+
+  return nullptr;
+}
+
 /**
  * A recursive function to double-check the result of is_derived_from().  This
  * is the slow, examine-the-whole-graph approach, as opposed to the clever and

+ 5 - 0
dtool/src/dtoolbase/typeRegistryNode.h

@@ -37,6 +37,8 @@ public:
   static TypeHandle get_parent_towards(const TypeRegistryNode *child,
                                        const TypeRegistryNode *base);
 
+  INLINE PyObject *get_python_type() const;
+
   void clear_subtree();
   void define_subtree();
 
@@ -46,6 +48,7 @@ public:
   typedef std::vector<TypeRegistryNode *> Classes;
   Classes _parent_classes;
   Classes _child_classes;
+  PyObject *_python_type = nullptr;
 
   AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
 
@@ -77,6 +80,8 @@ private:
   void r_build_subtrees(TypeRegistryNode *top,
                         int bit_count, SubtreeMaskType bits);
 
+  PyObject *r_get_python_type() const;
+
   static bool check_derived_from(const TypeRegistryNode *child,
                                  const TypeRegistryNode *base);
 

+ 7 - 2
dtool/src/interrogate/functionRemap.cxx

@@ -960,8 +960,13 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
 
     } else if (!_has_this && _parameters.size() > 0 &&
                (_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0) {
-      // A non-explicit non-copy constructor might be eligible for coercion.
-      _flags |= F_coerce_constructor;
+      // A non-explicit non-copy constructor might be eligible for coercion,
+      // as long as it does not require explicit keyword args.
+      if ((_flags & F_explicit_args) == 0 ||
+          _args_type != InterfaceMaker::AT_keyword_args) {
+
+        _flags |= F_coerce_constructor;
+      }
     }
 
     // Constructors always take varargs, and possibly keyword args.

+ 150 - 48
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -31,13 +31,13 @@
 #include "cppSimpleType.h"
 #include "cppStructType.h"
 #include "cppExpression.h"
-#include "vector"
 #include "cppParameterList.h"
-#include "algorithm"
 #include "lineStream.h"
 
-#include <set>
+#include <algorithm>
 #include <map>
+#include <set>
+#include <vector>
 
 using std::dec;
 using std::hex;
@@ -821,10 +821,54 @@ write_prototypes(ostream &out_code, ostream *out_h) {
     }
   }
 
+  out_code << "/**\n";
+  out_code << " * Declarations for exported classes\n";
+  out_code << " */\n";
+
+  out_code << "static const Dtool_TypeDef exports[] = {\n";
+
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    Object *object = (*oi).second;
+
+    if (object->_itype.is_class() || object->_itype.is_struct()) {
+      CPPType *type = object->_itype._cpptype;
+
+      if (isExportThisRun(type) && is_cpp_type_legal(type)) {
+        string class_name = type->get_local_name(&parser);
+        string safe_name = make_safe_name(class_name);
+
+        out_code << "  {\"" << class_name << "\", &Dtool_" << safe_name << "},\n";
+      }
+    }
+  }
+
+  out_code << "  {nullptr, nullptr},\n";
+  out_code << "};\n\n";
+
   out_code << "/**\n";
   out_code << " * Extern declarations for imported classes\n";
   out_code << " */\n";
 
+  // Write out a table of the externally imported types that will be filled in
+  // upon module initialization.
+  if (!_external_imports.empty()) {
+    out_code << "#ifndef LINK_ALL_STATIC\n";
+    out_code << "static Dtool_TypeDef imports[] = {\n";
+
+    int idx = 0;
+    for (CPPType *type : _external_imports) {
+      string class_name = type->get_local_name(&parser);
+      string safe_name = make_safe_name(class_name);
+
+      out_code << "  {\"" << class_name << "\", nullptr},\n";
+      out_code << "#define Dtool_Ptr_" << safe_name << " (imports[" << idx << "].type)\n";
+      ++idx;
+    }
+    out_code << "  {nullptr, nullptr},\n";
+    out_code << "};\n";
+    out_code << "#endif\n\n";
+  }
+
   for (CPPType *type : _external_imports) {
     string class_name = type->get_local_name(&parser);
     string safe_name = make_safe_name(class_name);
@@ -834,7 +878,9 @@ write_prototypes(ostream &out_code, ostream *out_h) {
     out_code << "#ifndef LINK_ALL_STATIC\n";
     // out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" <<
     // safe_name << ";\n";
-    out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
+    //if (has_get_class_type_function(type)) {
+    //  out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
+    //}
     // out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" <<
     // safe_name << "\n"; out_code << "IMPORT_THIS void
     // Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n";
@@ -1258,36 +1304,36 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
 
   Objects::iterator oi;
 
-  out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n";
+  out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n"
+         "  TypeRegistry *registry = TypeRegistry::ptr();\n"
+         "  nassertv(registry != nullptr);\n";
+
   for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
     Object *object = (*oi).second;
-    if (object->_itype.is_class() ||
-        object->_itype.is_struct()) {
-      if (is_cpp_type_legal(object->_itype._cpptype) &&
-          isExportThisRun(object->_itype._cpptype)) {
-        string class_name = make_safe_name(object->_itype.get_scoped_name());
-        bool is_typed = has_get_class_type_function(object->_itype._cpptype);
+    if (object->_itype.is_class() || object->_itype.is_struct()) {
+      CPPType *type = object->_itype._cpptype;
+      if (is_cpp_type_legal(type) && isExportThisRun(type)) {
+        string class_name = object->_itype.get_scoped_name();
+        string safe_name = make_safe_name(class_name);
+        bool is_typed = has_get_class_type_function(type);
 
         if (is_typed) {
-          if (has_init_type_function(object->_itype._cpptype)) {
+          out << "  {\n";
+          if (has_init_type_function(type)) {
             // Call the init_type function.  This isn't necessary for all
             // types as many of them are automatically initialized at static
             // init type, but for some extension classes it's useful.
-            out << "  " << object->_itype._cpptype->get_local_name(&parser)
+            out << "    " << type->get_local_name(&parser)
                 << "::init_type();\n";
           }
-          out << "  Dtool_" << class_name << "._type = "
-              << object->_itype._cpptype->get_local_name(&parser)
-              << "::get_class_type();\n"
-              << "  RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n";
-
+          out << "    TypeHandle handle = " << type->get_local_name(&parser)
+              << "::get_class_type();\n";
+          out << "    Dtool_" << safe_name << "._type = handle;\n";
+          out << "    registry->record_python_type(handle, "
+                 "(PyObject *)&Dtool_" << safe_name << ");\n";
+          out << "  }\n";
         } else {
-          out << "#ifndef LINK_ALL_STATIC\n"
-              << "  RegisterNamedClass(\"" << object->_itype.get_scoped_name()
-              << "\", Dtool_" << class_name << ");\n"
-              << "#endif\n";
-
-          if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) {
+          if (IsPandaTypedObject(type->as_struct_type())) {
             nout << object->_itype.get_scoped_name() << " derives from TypedObject, "
                  << "but does not define a get_class_type() function.\n";
           }
@@ -1297,23 +1343,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
   }
   out << "}\n\n";
 
-  out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n";
-  out << "#ifndef LINK_ALL_STATIC\n";
-  out << "  // Resolve externally imported types.\n";
-
-  for (CPPType *type : _external_imports) {
-    string class_name = type->get_local_name(&parser);
-    string safe_name = make_safe_name(class_name);
-
-    if (has_get_class_type_function(type)) {
-      out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
-    } else {
-      out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
-    }
-  }
-  out << "#endif\n";
-  out << "}\n\n";
-
   out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n";
   out << "  (void) module;\n";
 
@@ -1466,9 +1495,18 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
 
   out << "  {nullptr, nullptr, 0, nullptr}\n" << "};\n\n";
 
-  out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n";
+  if (_external_imports.empty()) {
+    out << "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, nullptr};\n";
+  } else {
+    out <<
+      "#ifdef LINK_ALL_STATIC\n"
+      "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, nullptr};\n"
+      "#else\n"
+      "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, imports};\n"
+      "#endif\n";
+  }
   if (out_h != nullptr) {
-    *out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n";
+    *out_h << "extern const struct LibraryDef " << def->library_name << "_moddef;\n";
   }
 }
 
@@ -1610,6 +1648,16 @@ write_module_class(ostream &out, Object *obj) {
 
     if (!func->_has_this) {
       flags += " | METH_STATIC";
+
+      // Skip adding this entry if we also have a property with the same name.
+      // In that case, we will use a Dtool_StaticProperty to disambiguate
+      // access to this method.  See GitHub issue #444.
+      for (const Property *property : obj->_properties) {
+        if (property->_has_this &&
+            property->_ielement.get_name() == func->_ifunc.get_name()) {
+          continue;
+        }
+      }
     }
 
     bool has_nonslotted = false;
@@ -2627,6 +2675,14 @@ write_module_class(ostream &out, Object *obj) {
         continue;
       }
 
+      // Actually, if we have a conflicting static method with the same name,
+      // we will need to use Dtool_StaticProperty instead.
+      for (const Function *func : obj->_methods) {
+        if (!func->_has_this && func->_ifunc.get_name() == ielem.get_name()) {
+          continue;
+        }
+      }
+
       if (num_getset == 0) {
         out << "static PyGetSetDef Dtool_Properties_" << ClassName << "[] = {\n";
       }
@@ -3063,7 +3119,7 @@ write_module_class(ostream &out, Object *obj) {
 
     out << "    Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
   } else {
-    out << "    Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n";
+    out << "    Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n";
   }
 
   int num_nested = obj->_itype.number_of_nested_types();
@@ -3202,9 +3258,23 @@ write_module_class(ostream &out, Object *obj) {
   // Also add the static properties, which can't be added via getset.
   for (Property *property : obj->_properties) {
     const InterrogateElement &ielem = property->_ielement;
-    if (property->_has_this || property->_getter_remaps.empty()) {
+    if (property->_getter_remaps.empty()) {
       continue;
     }
+    if (property->_has_this) {
+      // Actually, continue if we have a conflicting static method with the
+      // same name, which may still require use of Dtool_StaticProperty.
+      bool have_shadow = false;
+      for (const Function *func : obj->_methods) {
+        if (!func->_has_this && func->_ifunc.get_name() == ielem.get_name()) {
+          have_shadow = true;
+          break;
+        }
+      }
+      if (!have_shadow) {
+        continue;
+      }
+    }
 
     string name1 = methodNameFromCppName(ielem.get_name(), "", false);
     // string name2 = methodNameFromCppName(ielem.get_name(), "", true);
@@ -6858,8 +6928,42 @@ write_getset(ostream &out, Object *obj, Property *property) {
 
   // Now write the actual getter wrapper.  It will be a different wrapper
   // depending on whether it's a mapping or a sequence.
+  out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
+
+  // Is this property shadowing a static method with the same name?  This is a
+  // special case to handle WindowProperties::make -- see GH #444.
+  if (property->_has_this) {
+    for (const Function *func : obj->_methods) {
+      if (!func->_has_this && func->_ifunc.get_name() == ielem.get_name()) {
+        string flags;
+        string fptr = "&" + func->_name;
+        switch (func->_args_type) {
+        case AT_keyword_args:
+          flags = "METH_VARARGS | METH_KEYWORDS";
+          fptr = "(PyCFunction) " + fptr;
+          break;
+        case AT_varargs:
+          flags = "METH_VARARGS";
+          break;
+        case AT_single_arg:
+          flags = "METH_O";
+          break;
+        default:
+          flags = "METH_NOARGS";
+          break;
+        }
+        out << "  if (self == nullptr) {\n"
+            << "    static PyMethodDef def = {\"" << ielem.get_name() << "\", "
+            << fptr << ", " << flags << " | METH_STATIC, (const char *)"
+            << func->_name << "_comment};\n"
+            << "    return PyCFunction_New(&def, nullptr);\n"
+            << "  }\n\n";
+        break;
+      }
+    }
+  }
+
   if (ielem.is_mapping()) {
-    out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
     if (property->_has_this) {
       out << "  nassertr(self != nullptr, nullptr);\n";
     }
@@ -6886,7 +6990,6 @@ write_getset(ostream &out, Object *obj, Property *property) {
             "}\n\n";
 
   } else if (ielem.is_sequence()) {
-    out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
     if (property->_has_this) {
       out << "  nassertr(self != nullptr, nullptr);\n";
     }
@@ -6917,7 +7020,6 @@ write_getset(ostream &out, Object *obj, Property *property) {
 
   } else {
     // Write out a regular, unwrapped getter.
-    out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
     FunctionRemap *remap = property->_getter_remaps.front();
 
     if (remap->_has_this) {

+ 2 - 2
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -11,8 +11,8 @@
 
 #ifndef INTERFACEMAKERPYTHONNATIVE_H
 #define INTERFACEMAKERPYTHONNATIVE_H
-#include "map"
-#include "set"
+#include <map>
+#include <set>
 #include "dtoolbase.h"
 
 #include "interfaceMakerPython.h"

+ 0 - 3
dtool/src/interrogate/interrogate.cxx

@@ -19,7 +19,6 @@
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 
 using std::cerr;
@@ -309,8 +308,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 int
 main(int argc, char **argv) {
-  pystub();
-
   preprocess_argv(argc, argv);
   string command_line;
   int i;

+ 9 - 14
dtool/src/interrogate/interrogate_module.cxx

@@ -19,7 +19,6 @@
 #include "interrogate_interface.h"
 #include "interrogate_request.h"
 #include "load_dso.h"
-#include "pystub.h"
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
@@ -30,6 +29,9 @@
 using std::cerr;
 using std::string;
 
+// This contains a big source string determined at compile time.
+extern const char interrogate_preamble_python_native[];
+
 Filename output_code_filename;
 string module_name;
 string library_name;
@@ -286,9 +288,8 @@ int write_python_table_native(std::ostream &out) {
   vector_string::const_iterator ii;
   for (ii = libraries.begin(); ii != libraries.end(); ++ii) {
     printf("Referencing Library %s\n", (*ii).c_str());
-    out << "extern LibraryDef " << *ii << "_moddef;\n";
+    out << "extern const struct LibraryDef " << *ii << "_moddef;\n";
     out << "extern void Dtool_" << *ii << "_RegisterTypes();\n";
-    out << "extern void Dtool_" << *ii << "_ResolveExternals();\n";
     out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n";
   }
 
@@ -339,12 +340,9 @@ int write_python_table_native(std::ostream &out) {
   for (ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "  Dtool_" << *ii << "_RegisterTypes();\n";
   }
-  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
-    out << "  Dtool_" << *ii << "_ResolveExternals();\n";
-  }
   out << "\n";
 
-  out << "  LibraryDef *defs[] = {";
+  out << "  const LibraryDef *defs[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
   }
@@ -386,12 +384,9 @@ int write_python_table_native(std::ostream &out) {
   for (ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "  Dtool_" << *ii << "_RegisterTypes();\n";
   }
-  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
-    out << "  Dtool_" << *ii << "_ResolveExternals();\n";
-  }
   out << "\n";
 
-  out << "  LibraryDef *defs[] = {";
+  out << "  const LibraryDef *defs[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
   }
@@ -545,8 +540,6 @@ int main(int argc, char *argv[]) {
   extern int optind;
   int flag;
 
-  pystub();
-
   preprocess_argv(argc, argv);
   flag = getopt_long_only(argc, argv, short_options, long_options, nullptr);
   while (flag != EOF) {
@@ -642,8 +635,10 @@ int main(int argc, char *argv[]) {
 
       if (build_python_native_wrappers) {
         write_python_table_native(output_code);
-      }
 
+        // Output the support code.
+        output_code << interrogate_preamble_python_native << "\n";
+      }
     }
   }
 

+ 0 - 3
dtool/src/interrogate/parse_file.cxx

@@ -22,7 +22,6 @@
 #include "cppGlobals.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <stdlib.h>
 
 using std::cerr;
@@ -206,8 +205,6 @@ show_nested_types(const string &str) {
 
 int
 main(int argc, char **argv) {
-  pystub();
-
   extern char *optarg;
   extern int optind;
   const char *optstr = "I:S:D:o:l:vp";

+ 103 - 91
dtool/src/interrogatedb/dtool_super_base.cxx

@@ -15,120 +15,132 @@
 
 #ifdef HAVE_PYTHON
 
-class EmptyClass {
-};
-Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
-
 static PyObject *GetSuperBase(PyObject *self) {
-  Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
-  return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
-};
-
-PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
-  { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
-  { nullptr, nullptr, 0, nullptr }
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions
+  return (PyObject *)super_base;
 };
 
-EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
-  static bool initdone = false;
-  if (!initdone) {
-
-    initdone = true;
-    Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New();
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict);
-
-    if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
-      PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
-      return;
-    }
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
-  }
-
+static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
   if (module != nullptr) {
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
+    Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+    Py_INCREF((PyTypeObject *)&super_base);
+    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base);
   }
 }
 
-inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
+static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
   return nullptr;
 }
 
-inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
+static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
   return nullptr;
 }
 
-int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
+static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
   assert(self != nullptr);
   PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name);
   return -1;
 }
 
-EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
-  {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "dtoolconfig.DTOOL_SUPER_BASE",
-    sizeof(Dtool_PyInstDef),
-    0, // tp_itemsize
-    &Dtool_FreeInstance_DTOOL_SUPER_BASE,
-    nullptr, // tp_print
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
+static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) {
+  Py_TYPE(self)->tp_free(self);
+}
+
+/**
+ * Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of
+ * all Panda types.  This pointer is shared by all modules.
+ */
+Dtool_PyTypedObject *Dtool_GetSuperBase() {
+  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
+  auto it = type_map->find("DTOOL_SUPER_BASE");
+  if (it != type_map->end()) {
+    return it->second;
+  }
+
+  static PyMethodDef methods[] = {
+    { "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
+    { nullptr, nullptr, 0, nullptr }
+  };
+
+  static Dtool_PyTypedObject super_base_type = {
+    {
+      PyVarObject_HEAD_INIT(nullptr, 0)
+      "dtoolconfig.DTOOL_SUPER_BASE",
+      sizeof(Dtool_PyInstDef),
+      0, // tp_itemsize
+      &Dtool_FreeInstance_DTOOL_SUPER_BASE,
+      nullptr, // tp_print
+      nullptr, // tp_getattr
+      nullptr, // tp_setattr
 #if PY_MAJOR_VERSION >= 3
-    nullptr, // tp_compare
+      nullptr, // tp_compare
 #else
-    &DtoolInstance_ComparePointers,
+      &DtoolInstance_ComparePointers,
 #endif
-    nullptr, // tp_repr
-    nullptr, // tp_as_number
-    nullptr, // tp_as_sequence
-    nullptr, // tp_as_mapping
-    &DtoolInstance_HashPointer,
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
+      nullptr, // tp_repr
+      nullptr, // tp_as_number
+      nullptr, // tp_as_sequence
+      nullptr, // tp_as_mapping
+      &DtoolInstance_HashPointer,
+      nullptr, // tp_call
+      nullptr, // tp_str
+      PyObject_GenericGetAttr,
+      PyObject_GenericSetAttr,
+      nullptr, // tp_as_buffer
+      (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
+      nullptr, // tp_doc
+      nullptr, // tp_traverse
+      nullptr, // tp_clear
 #if PY_MAJOR_VERSION >= 3
-    &DtoolInstance_RichComparePointers,
+      &DtoolInstance_RichComparePointers,
 #else
-    nullptr, // tp_richcompare
+      nullptr, // tp_richcompare
 #endif
-    0, // tp_weaklistoffset
-    nullptr, // tp_iter
-    nullptr, // tp_iternext
-    Dtool_Methods_DTOOL_SUPER_BASE,
-    standard_type_members,
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    Dtool_Init_DTOOL_SUPER_BASE,
-    PyType_GenericAlloc,
-    Dtool_new_DTOOL_SUPER_BASE,
-    PyObject_Del,
-    nullptr, // tp_is_gc
-    nullptr, // tp_bases
-    nullptr, // tp_mro
-    nullptr, // tp_cache
-    nullptr, // tp_subclasses
-    nullptr, // tp_weaklist
-    nullptr, // tp_del
-  },
-  TypeHandle::none(),
-  Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
-  Dtool_UpcastInterface_DTOOL_SUPER_BASE,
-  Dtool_DowncastInterface_DTOOL_SUPER_BASE,
-  nullptr,
-  nullptr,
-};
+      0, // tp_weaklistoffset
+      nullptr, // tp_iter
+      nullptr, // tp_iternext
+      methods,
+      standard_type_members,
+      nullptr, // tp_getset
+      nullptr, // tp_base
+      nullptr, // tp_dict
+      nullptr, // tp_descr_get
+      nullptr, // tp_descr_set
+      0, // tp_dictoffset
+      Dtool_Init_DTOOL_SUPER_BASE,
+      PyType_GenericAlloc,
+      nullptr, // tp_new
+      PyObject_Del,
+      nullptr, // tp_is_gc
+      nullptr, // tp_bases
+      nullptr, // tp_mro
+      nullptr, // tp_cache
+      nullptr, // tp_subclasses
+      nullptr, // tp_weaklist
+      nullptr, // tp_del
+    },
+    TypeHandle::none(),
+    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
+    Dtool_UpcastInterface_DTOOL_SUPER_BASE,
+    Dtool_DowncastInterface_DTOOL_SUPER_BASE,
+    nullptr,
+    nullptr,
+  };
+
+  super_base_type._PyType.tp_dict = PyDict_New();
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict);
+
+  if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) {
+    PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
+    return nullptr;
+  }
+  Py_INCREF((PyTypeObject *)&super_base_type);
+
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type));
+
+  (*type_map)["DTOOL_SUPER_BASE"] = &super_base_type;
+  return &super_base_type;
+}
 
 #endif  // HAVE_PYTHON

+ 0 - 1
dtool/src/interrogatedb/p3interrogatedb_composite1.cxx

@@ -1,5 +1,4 @@
 #include "config_interrogatedb.cxx"
-#include "dtool_super_base.cxx"
 #include "indexRemapper.cxx"
 #include "interrogateComponent.cxx"
 #include "interrogateDatabase.cxx"

+ 0 - 3
dtool/src/interrogatedb/p3interrogatedb_composite2.cxx

@@ -4,6 +4,3 @@
 #include "interrogate_datafile.cxx"
 #include "interrogate_interface.cxx"
 #include "interrogate_request.cxx"
-#include "py_panda.cxx"
-#include "py_compat.cxx"
-#include "py_wrappers.cxx"

+ 0 - 7
dtool/src/interrogatedb/py_compat.cxx

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_compat.cxx
  * @author rdb
  * @date 2017-12-03

+ 2 - 9
dtool/src/interrogatedb/py_compat.h

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_compat.h
  * @author rdb
  * @date 2017-12-02
@@ -36,7 +29,7 @@
 // See PEP 353
 #define PY_SSIZE_T_CLEAN 1
 
-#include "Python.h"
+#include <Python.h>
 
 /* Python 2.4 */
 
@@ -106,7 +99,7 @@ typedef int Py_ssize_t;
 // PyInt_FromSize_t automatically picks the right type.
 #  define PyLongOrInt_AS_LONG PyInt_AsLong
 
-EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *);
+size_t PyLongOrInt_AsSize_t(PyObject *);
 #endif
 
 // Which character to use in PyArg_ParseTuple et al for a byte string.

+ 17 - 12
dtool/src/interrogatedb/py_panda.I

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_panda.I
  * @author rdb
  * @date 2016-06-06
@@ -26,7 +19,7 @@
 template<class T> INLINE bool
 DtoolInstance_GetPointer(PyObject *self, T *&into) {
   if (DtoolInstance_Check(self)) {
-    Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+    Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
     if (target_class != nullptr) {
       if (_IS_FINAL(T)) {
         if (DtoolInstance_TYPE(self) == target_class) {
@@ -116,32 +109,44 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) {
  */
 template<class T> INLINE PyObject *
 DTool_CreatePyInstance(const T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstance(T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
 }
 
+/**
+ * Finishes initializing the Dtool_PyInstDef.
+ */
+INLINE int
+DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
+  ((Dtool_PyInstDef *)self)->_My_Type = type;
+  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
+  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
+  ((Dtool_PyInstDef *)self)->_is_const = is_const;
+  return 0;
+}
+
 /**
  * Checks that the tuple is empty.
  */

+ 48 - 174
dtool/src/interrogatedb/py_panda.cxx

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_panda.cxx
  * @author drose
  * @date 2005-07-04
@@ -29,10 +22,6 @@ PyMemberDef standard_type_members[] = {
   {nullptr}  /* Sentinel */
 };
 
-static RuntimeTypeMap runtime_type_map;
-static RuntimeTypeSet runtime_type_set;
-static NamedTypeMap named_type_map;
-
 /**
 
  */
@@ -431,7 +420,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
   // IF the class is possibly a run time typed object
   if (type_index > 0) {
     // get best fit class...
-    Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index);
+    Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type();
     if (target_class != nullptr) {
       // cast to the type...
       void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type);
@@ -484,132 +473,26 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
   return (PyObject *)self;
 }
 
-// Th Finalizer for simple instances..
-int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
-  // lets put some code in here that checks to see the memory is properly
-  // configured.. prior to my call ..
-
-  ((Dtool_PyInstDef *)self)->_My_Type = type;
-  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
-  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
-  ((Dtool_PyInstDef *)self)->_is_const = is_const;
-  return 0;
-}
-
-// A helper function to glue method definition together .. that can not be
-// done at code generation time because of multiple generation passes in
-// interrogate..
-void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
-  for (; in->ml_name != nullptr; in++) {
-    if (themap.find(in->ml_name) == themap.end()) {
-      themap[in->ml_name] = in;
-    }
-  }
-}
-
-// ** HACK ** alert.. Need to keep a runtime type dictionary ... that is
-// forward declared of typed object.  We rely on the fact that typed objects
-// are uniquly defined by an integer.
-void
-RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) {
-  std::pair<NamedTypeMap::iterator, bool> result =
-    named_type_map.insert(NamedTypeMap::value_type(name, &otype));
-
-  if (!result.second) {
-    // There was already a class with this name in the dictionary.
-    interrogatedb_cat.warning()
-      << "Double definition for class " << name << "\n";
-  }
-}
-
-void
-RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) {
-  int type_index = otype._type.get_index();
-
-  if (type_index == 0) {
-    interrogatedb_cat.warning()
-      << "Class " << otype._PyType.tp_name
-      << " has a zero TypeHandle value; check that init_type() is called.\n";
-
-  } else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) {
-    interrogatedb_cat.warning()
-      << "Class " << otype._PyType.tp_name
-      << " has an illegal TypeHandle value; check that init_type() is called.\n";
-
-  } else {
-    std::pair<RuntimeTypeMap::iterator, bool> result =
-      runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype));
-    if (!result.second) {
-      // There was already an entry in the dictionary for type_index.
-      Dtool_PyTypedObject *other_type = (*result.first).second;
-      interrogatedb_cat.warning()
-        << "Classes " << otype._PyType.tp_name
-        << " and " << other_type->_PyType.tp_name
-        << " share the same TypeHandle value (" << type_index
-        << "); check class definitions.\n";
-
-    } else {
-      runtime_type_set.insert(type_index);
-    }
-  }
-}
-
-Dtool_PyTypedObject *
-LookupNamedClass(const string &name) {
-  NamedTypeMap::const_iterator it;
-  it = named_type_map.find(name);
-
-  if (it == named_type_map.end()) {
-    // Find a type named like this in the type registry.
-    TypeHandle handle = TypeRegistry::ptr()->find_type(name);
-    if (handle.get_index() > 0) {
-      RuntimeTypeMap::const_iterator it2;
-      it2 = runtime_type_map.find(handle.get_index());
-      if (it2 != runtime_type_map.end()) {
-        return it2->second;
-      }
-    }
-
-    interrogatedb_cat.error()
-      << "Attempt to use type " << name << " which has not yet been defined!\n";
-    return nullptr;
-  } else {
-    return it->second;
-  }
-}
-
-Dtool_PyTypedObject *
-LookupRuntimeTypedClass(TypeHandle handle) {
-  RuntimeTypeMap::const_iterator it;
-  it = runtime_type_map.find(handle.get_index());
-
-  if (it == runtime_type_map.end()) {
-    interrogatedb_cat.error()
-      << "Attempt to use type " << handle << " which has not yet been defined!\n";
-    return nullptr;
-  } else {
-    return it->second;
-  }
-}
-
-Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
-  RuntimeTypeMap::iterator di = runtime_type_map.find(type);
-  if (di != runtime_type_map.end()) {
-    return di->second;
+/**
+ * Returns a borrowed reference to the global type dictionary.
+ */
+Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
+  PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
+  if (capsule != nullptr) {
+    return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
   } else {
-    int type2 = get_best_parent_from_Set(type, runtime_type_set);
-    di = runtime_type_map.find(type2);
-    if (di != runtime_type_map.end()) {
-      return di->second;
-    }
+    Dtool_TypeMap *type_map = new Dtool_TypeMap;
+    capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
+    PySys_SetObject((char *)"_interrogate_types", capsule);
+    Py_DECREF(capsule);
+    return type_map;
   }
-  return nullptr;
 }
 
 #if PY_MAJOR_VERSION >= 3
-PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) {
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) {
 #else
-PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename) {
 #endif
   // Check the version so we can print a helpful error if it doesn't match.
   string version = Py_GetVersion();
@@ -627,55 +510,46 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
     return nullptr;
   }
 
-  // Initialize the types we define in py_panda.
-  static bool dtool_inited = false;
-  if (!dtool_inited) {
-    dtool_inited = true;
-
-    if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)");
-    }
+  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)");
-    }
+  // the module level function inits....
+  MethodDefmap functions;
+  for (size_t i = 0; defs[i] != nullptr; i++) {
+    const LibraryDef &def = *defs[i];
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)");
+    // Accumulate method definitions.
+    for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) {
+      if (functions.find(meth->ml_name) == functions.end()) {
+        functions[meth->ml_name] = meth;
+      }
     }
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)");
+    // Define exported types.
+    const Dtool_TypeDef *types = def._types;
+    if (types != nullptr) {
+      while (types->name != nullptr) {
+        (*type_map)[std::string(types->name)] = types->type;
+        ++types;
+      }
     }
+  }
 
-    if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)");
-    }
+  // Resolve external types, in a second pass.
+  for (size_t i = 0; defs[i] != nullptr; i++) {
+    const LibraryDef &def = *defs[i];
 
-    if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
+    Dtool_TypeDef *types = def._external_types;
+    if (types != nullptr) {
+      while (types->name != nullptr) {
+        auto it = type_map->find(std::string(types->name));
+        if (it != type_map->end()) {
+          types->type = it->second;
+        } else {
+          return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
+        }
+        ++types;
+      }
     }
-
-    // Initialize the base class of everything.
-    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr);
-  }
-
-  // the module level function inits....
-  MethodDefmap functions;
-  for (int xx = 0; defs[xx] != nullptr; xx++) {
-    Dtool_Accum_MethDefs(defs[xx]->_methods, functions);
   }
 
   PyMethodDef *newdef = new PyMethodDef[functions.size() + 1];
@@ -799,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
 
 // We do expose a dictionay for dtool classes .. this should be removed at
 // some point..
-EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
+PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
   PyObject *self;
   PyObject *subject;
   PyObject *key;

+ 43 - 54
dtool/src/interrogatedb/py_panda.h

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_panda.h
  */
 
@@ -28,7 +21,7 @@
 
 // py_compat.h includes Python.h.
 #include "py_compat.h"
-#include "structmember.h"
+#include <structmember.h>
 
 using namespace std;
 
@@ -43,9 +36,6 @@ using namespace std;
 #endif
 
 struct Dtool_PyTypedObject;
-typedef std::map<int, Dtool_PyTypedObject *> RuntimeTypeMap;
-typedef std::set<int> RuntimeTypeSet;
-typedef std::map<std::string, Dtool_PyTypedObject *> NamedTypeMap;
 
 // used to stamp dtool instance..
 #define PY_PANDA_SIGNATURE 0xbeaf
@@ -78,7 +68,7 @@ struct Dtool_PyInstDef {
 };
 
 // A Offset Dictionary Defining How to read the Above Object..
-extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[];
+extern PyMemberDef standard_type_members[];
 
 // The Class Definition Structor For a Dtool python type.
 struct Dtool_PyTypedObject {
@@ -190,25 +180,21 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
 // forward declared of typed object.  We rely on the fact that typed objects
 // are uniquly defined by an integer.
 
-EXPCL_INTERROGATEDB void RegisterNamedClass(const std::string &name, Dtool_PyTypedObject &otype);
-EXPCL_INTERROGATEDB void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype);
+typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
 
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupNamedClass(const std::string &name);
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle);
-
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
+Dtool_TypeMap *Dtool_GetGlobalTypeMap();
 
 /**
 
  */
-EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
+void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
 
-EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
+void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
+bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
-                                                              void **answer, const char *method_name);
+bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
+                                            void **answer, const char *method_name);
 
 template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into);
 template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef);
@@ -218,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2);
 INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op);
 
 // Functions related to error reporting.
-EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
+bool _Dtool_CheckErrorOccurred();
 
 #ifdef NDEBUG
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
@@ -226,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
 #endif
 
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError();
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
+PyObject *Dtool_Raise_AssertionError();
+PyObject *Dtool_Raise_TypeError(const char *message);
+PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
+PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
 
-EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
+PyObject *_Dtool_Raise_BadArgumentsError();
 #ifdef NDEBUG
 // Define it to a function that just prints a generic message.
 #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
@@ -243,9 +229,9 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
 // These functions are similar to Dtool_WrapValue, except that they also
 // contain code for checking assertions and exceptions when compiling with
 // NDEBUG mode on.
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None();
-EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value);
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
+PyObject *_Dtool_Return_None();
+PyObject *Dtool_Return_Bool(bool value);
+PyObject *_Dtool_Return(PyObject *value);
 
 #ifdef NDEBUG
 #define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
@@ -258,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
 /**
  * Wrapper around Python 3.4's enum library, which does not have a C API.
  */
-EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
+PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
                                                         const char *module = nullptr);
-EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value);
+INLINE long Dtool_EnumValue_AsLong(PyObject *value);
 
 
 /**
 
  */
-EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
+PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
 
 // DTool_CreatePyInstance .. wrapper function to finalize the existance of a
 // general dtool py instance..
-EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
+PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
 
 // These template methods allow use when the Dtool_PyTypedObject is not known.
 // They require a get_class_type() to be defined for the class.
@@ -314,43 +300,49 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
 
 // The finalizer for simple instances.
-EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
+INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
 
 // A heler function to glu methed definition together .. that can not be done
 // at code generation time becouse of multiple generation passes in
 // interigate..
 typedef std::map<std::string, PyMethodDef *> MethodDefmap;
 
-EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
-
 // We need a way to runtime merge compile units into a python "Module" .. this
 // is done with the fallowing structors and code.. along with the support of
 // interigate_module
+
+struct Dtool_TypeDef {
+  const char *const name;
+  Dtool_PyTypedObject *type;
+};
+
 struct LibraryDef {
-  PyMethodDef *_methods;
+  PyMethodDef *const _methods;
+  const Dtool_TypeDef *const _types;
+  Dtool_TypeDef *const _external_types;
 };
 
 #if PY_MAJOR_VERSION >= 3
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
 #else
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
 #endif
 
 // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to
 // grab the "THIS" pointer from an object and use it Required to support fom
 // historical inharatence in the for of "is this instance of"..
-EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
+PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
 
 #define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer
 #define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_make_copy(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_copy_constructor(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 map_deepcopy_to_copy(PyObject *self, PyObject *args);
 
 /**
@@ -359,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args);
  */
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args);
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds);
 
 /**
@@ -401,10 +393,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value);
 template<class T1, class T2>
 ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair<T1, T2> &value);
 
-EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
-EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
-
-#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
+Dtool_PyTypedObject *Dtool_GetSuperBase();
 
 #include "py_panda.I"
 

File diff suppressed because it is too large
+ 299 - 674
dtool/src/interrogatedb/py_wrappers.cxx


+ 6 - 23
dtool/src/interrogatedb/py_wrappers.h

@@ -1,11 +1,4 @@
 /**
- * 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."
- *
  * @file py_wrappers.h
  * @author rdb
  * @date 2017-11-26
@@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper {
   iternextfunc _iternext_func;
 };
 
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
-
-EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
+Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
+Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
+PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func);
+PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
 
 #endif  // HAVE_PYTHON
 

+ 0 - 3
dtool/src/parser-inc/Python.h

@@ -47,9 +47,6 @@ PyObject _Py_FalseStruct;
 #define Py_False ((PyObject *) &_Py_FalseStruct)
 #endif
 
-// This file defines PY_VERSION_HEX, which is used in some places.
-#include "patchlevel.h"
-
 typedef void *visitproc;
 
 #endif  // PYTHON_H

+ 1 - 1
dtool/src/prc/configPage.cxx

@@ -22,7 +22,7 @@
 #include <ctype.h>
 
 #ifdef HAVE_OPENSSL
-#include "openssl/evp.h"
+#include <openssl/evp.h>
 #endif
 
 using std::istream;

+ 2 - 2
dtool/src/prc/encryptStreamBuf.cxx

@@ -20,8 +20,8 @@
 
 #ifdef HAVE_OPENSSL
 
-#include "openssl/rand.h"
-#include "openssl/evp.h"
+#include <openssl/rand.h>
+#include <openssl/evp.h>
 
 // The iteration count is scaled by this factor for writing to the stream.
 static const int iteration_count_factor = 1000;

+ 2 - 2
dtool/src/prc/prcKeyRegistry.cxx

@@ -19,8 +19,8 @@
 
 #ifdef HAVE_OPENSSL
 
-#include "openssl/evp.h"
-#include "openssl/pem.h"
+#include <openssl/evp.h>
+#include <openssl/pem.h>
 
 // Some versions of OpenSSL appear to define this as a macro.  Yucky.
 #undef set_key

+ 5 - 5
dtool/src/prckeys/makePrcKey.cxx

@@ -24,11 +24,11 @@
 #include PRC_PUBLIC_KEYS_INCLUDE
 #endif
 
-#include "openssl/rsa.h"
-#include "openssl/err.h"
-#include "openssl/pem.h"
-#include "openssl/rand.h"
-#include "openssl/bio.h"
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
 
 using std::cerr;
 using std::string;

+ 5 - 5
dtool/src/prckeys/signPrcFile_src.cxx

@@ -24,11 +24,11 @@
 
 #include <time.h>
 
-#include "openssl/err.h"
-#include "openssl/pem.h"
-#include "openssl/rand.h"
-#include "openssl/bio.h"
-#include "openssl/evp.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
 
 using std::cerr;
 using std::string;

+ 8 - 0
dtool/src/pystub/pystub.cxx

@@ -27,6 +27,8 @@ extern "C" {
   EXPCL_PYSTUB int PyCFunction_New(...);
   EXPCL_PYSTUB int PyCFunction_NewEx(...);
   EXPCL_PYSTUB int PyCallable_Check(...);
+  EXPCL_PYSTUB int PyCapsule_GetPointer(...);
+  EXPCL_PYSTUB int PyCapsule_New(...);
   EXPCL_PYSTUB int PyDict_DelItem(...);
   EXPCL_PYSTUB int PyDict_DelItemString(...);
   EXPCL_PYSTUB int PyDict_GetItem(...);
@@ -133,6 +135,7 @@ extern "C" {
   EXPCL_PYSTUB int PyString_InternInPlace(...);
   EXPCL_PYSTUB int PyString_Size(...);
   EXPCL_PYSTUB int PySys_GetObject(...);
+  EXPCL_PYSTUB int PySys_SetObject(...);
   EXPCL_PYSTUB int PyThreadState_Clear(...);
   EXPCL_PYSTUB int PyThreadState_Delete(...);
   EXPCL_PYSTUB int PyThreadState_Get(...);
@@ -216,6 +219,7 @@ extern "C" {
   EXPCL_PYSTUB extern void *PyExc_ImportError;
   EXPCL_PYSTUB extern void *PyExc_IndexError;
   EXPCL_PYSTUB extern void *PyExc_KeyError;
+  EXPCL_PYSTUB extern void *PyExc_NameError;
   EXPCL_PYSTUB extern void *PyExc_OSError;
   EXPCL_PYSTUB extern void *PyExc_OverflowError;
   EXPCL_PYSTUB extern void *PyExc_RuntimeError;
@@ -257,6 +261,8 @@ int PyBytes_Size(...) { return 0; }
 int PyCFunction_New(...) { return 0; };
 int PyCFunction_NewEx(...) { return 0; };
 int PyCallable_Check(...) { return 0; }
+int PyCapsule_GetPointer(...) { return 0; }
+int PyCapsule_New(...) { return 0; }
 int PyDict_DelItem(...) { return 0; }
 int PyDict_DelItemString(...) { return 0; }
 int PyDict_GetItem(...) { return 0; }
@@ -363,6 +369,7 @@ int PyString_FromStringAndSize(...) { return 0; }
 int PyString_InternFromString(...) { return 0; }
 int PyString_InternInPlace(...) { return 0; }
 int PySys_GetObject(...) { return 0; }
+int PySys_SetObject(...) { return 0; }
 int PyThreadState_Clear(...) { return 0; }
 int PyThreadState_Delete(...) { return 0; }
 int PyThreadState_Get(...) { return 0; }
@@ -452,6 +459,7 @@ void *PyExc_FutureWarning = nullptr;
 void *PyExc_ImportError = nullptr;
 void *PyExc_IndexError = nullptr;
 void *PyExc_KeyError = nullptr;
+void *PyExc_NameError = nullptr;
 void *PyExc_OSError = nullptr;
 void *PyExc_OverflowError = nullptr;
 void *PyExc_RuntimeError = nullptr;

+ 0 - 3
dtool/src/test_interrogate/test_interrogate.cxx

@@ -17,7 +17,6 @@
 #include "interrogate_request.h"
 #include "load_dso.h"
 #include "filename.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 
@@ -526,8 +525,6 @@ main(int argc, char **argv) {
   extern int optind;
   const char *optstr = "p:ftqh";
 
-  pystub();
-
   bool all_functions = false;
   bool all_types = false;
   bool quick_load = false;

+ 39 - 14
makepanda/installer.nsi

@@ -331,13 +331,24 @@ SectionGroup "Python support"
         SetOutPath $INSTDIR\panda3d
         File /r "${BUILT}\panda3d\*.py"
 
-        File /r /x bullet.pyd /x ode.pyd /x physx.pyd /x rocket.pyd "${BUILT}\panda3d\*.pyd"
+        File /nonfatal /r "${BUILT}\panda3d\core${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\ai${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\awesomium${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\direct${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\egg${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\fx${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\interrogatedb${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\physics${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\_rplight${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\skel${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\vision${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\vrpn${EXT_SUFFIX}"
 
         !ifdef HAVE_BULLET
             SectionGetFlags ${SecBullet} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipBulletPyd
-            File /nonfatal /r "${BUILT}\panda3d\bullet.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\bullet${EXT_SUFFIX}"
             SkipBulletPyd:
         !endif
 
@@ -345,7 +356,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecODE} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipODEPyd
-            File /nonfatal /r "${BUILT}\panda3d\ode.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\ode${EXT_SUFFIX}"
             SkipODEPyd:
         !endif
 
@@ -353,7 +364,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecPhysX} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd
-            File /nonfatal /r "${BUILT}\panda3d\physx.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\physx${EXT_SUFFIX}"
             SkipPhysXPyd:
         !endif
 
@@ -361,7 +372,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecRocket} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd
-            File /nonfatal /r "${BUILT}\panda3d\rocket.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\rocket${EXT_SUFFIX}"
             SkipRocketPyd:
         !endif
 
@@ -374,26 +385,36 @@ SectionGroup "Python support"
         SetRegView ${REGVIEW}
         !endif
 
-        ; Check for a system-wide Python installation.
-        ; We could check for a user installation of Python as well, but there
-        ; is no distinction between 64-bit and 32-bit regviews in HKCU, so we
-        ; can't guess whether it might be a compatible version.
+        ; Check for a non-Panda3D system-wide Python installation.
         ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+        StrCmp $0 "$INSTDIR\python" UserExternalPthCheck 0
+        StrCmp $0 "" UserExternalPthCheck 0
+        IfFileExists "$0\ppython.exe" UserExternalPthCheck 0
+        IfFileExists "$0\python.exe" AskExternalPth UserExternalPthCheck
+
+        ; Check for a non-Panda3D user installation of Python.
+        UserExternalPthCheck:
+        ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
         StrCmp $0 "$INSTDIR\python" SkipExternalPth 0
         StrCmp $0 "" SkipExternalPth 0
         IfFileExists "$0\ppython.exe" SkipExternalPth 0
-        IfFileExists "$0\python.exe" 0 SkipExternalPth
+        IfFileExists "$0\python.exe" AskExternalPth SkipExternalPth
 
         ; We're pretty sure this Python build is of the right architecture.
+        AskExternalPth:
         MessageBox MB_YESNO|MB_ICONQUESTION \
             "Your system already has a copy of Python ${PYVER} installed in:$\r$\n$0$\r$\nWould you like to configure it to be able to use the Panda3D libraries?$\r$\nIf you choose no, you will only be able to use Panda3D's own copy of Python." \
             IDYES WriteExternalPth IDNO SkipExternalPth
 
         WriteExternalPth:
-        FileOpen $1 "$0\Lib\site-packages\panda.pth" w
-        FileWrite $1 "$INSTDIR$\r$\n"
-        FileWrite $1 "$INSTDIR\bin$\r$\n"
-        FileClose $1
+        ;FileOpen $1 "$0\Lib\site-packages\panda.pth" w
+        ;FileWrite $1 "$INSTDIR$\r$\n"
+        ;FileWrite $1 "$INSTDIR\bin$\r$\n"
+        ;FileClose $1
+
+        ; Actually, it looks like we can just do this instead:
+        WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" "" "$INSTDIR"
+
         SkipExternalPth:
     SectionEnd
 
@@ -725,6 +746,10 @@ Section Uninstall
     StrCmp $0 "$INSTDIR\python" 0 +2
     DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}"
 
+    ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D" ""
+    StrCmp $0 "$INSTDIR" 0 +2
+    DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}\PythonPath\Panda3D"
+
     SetDetailsPrint both
     DetailPrint "Deleting files..."
     SetDetailsPrint listonly

+ 6 - 1
makepanda/installpanda.py

@@ -175,6 +175,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
     oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications")
     oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d")
     oscmd("mkdir -m 0755 -p "+destdir+PPATH)
+    oscmd("mkdir -m 0755 -p "+destdir+PPATH+"/panda3d")
 
     if (sys.platform.startswith("freebsd")):
         oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
@@ -194,13 +195,17 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
 
     oscmd("cp -R "+outputdir+"/include          "+destdir+prefix+"/include/panda3d")
     oscmd("cp -R "+outputdir+"/pandac           "+destdir+prefix+"/share/panda3d/")
-    oscmd("cp -R "+outputdir+"/panda3d          "+destdir+PPATH+"/")
     oscmd("cp -R "+outputdir+"/models           "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir("samples"):             oscmd("cp -R samples               "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/direct"):   oscmd("cp -R "+outputdir+"/direct           "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/Pmw"):      oscmd("cp -R "+outputdir+"/Pmw     "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/plugins"):  oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
 
+    suffix = GetExtensionSuffix()
+    for base in os.listdir(outputdir + "/panda3d"):
+        if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
+            oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+PPATH+"/panda3d/"+base)
+
     WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
     WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
     WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO)

File diff suppressed because it is too large
+ 209 - 259
makepanda/makepanda.py


+ 151 - 28
makepanda/makepandacore.py

@@ -150,7 +150,7 @@ CONFLICTING_FILES=["dtool/src/dtoolutil/pandaVersion.h",
 def WarnConflictingFiles(delete = False):
     for cfile in CONFLICTING_FILES:
         if os.path.exists(cfile):
-            print("%sWARNING:%s file may conflict with build: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), cfile, GetColor()))
+            Warn("file may conflict with build:", cfile)
             if delete:
                 os.unlink(cfile)
                 print("Deleted.")
@@ -284,6 +284,20 @@ def exit(msg = ""):
         print(msg)
         raise "initiate-exit"
 
+def Warn(msg, extra=None):
+    if extra is not None:
+        print("%sWARNING:%s %s %s%s%s" % (GetColor("red"), GetColor(), msg, GetColor("green"), extra, GetColor()))
+    else:
+        print("%sWARNING:%s %s" % (GetColor("red"), GetColor(), msg))
+    sys.stdout.flush()
+
+def Error(msg, extra=None):
+    if extra is not None:
+        print("%sERROR:%s %s %s%s%s" % (GetColor("red"), GetColor(), msg, GetColor("green"), extra, GetColor()))
+    else:
+        print("%sERROR:%s %s" % (GetColor("red"), GetColor(), msg))
+    exit()
+
 ########################################################################
 ##
 ## SetTarget, GetTarget, GetHost
@@ -723,7 +737,7 @@ def NeedsBuild(files, others):
                     print("    dependency changed: %s" % (key))
 
         if VERBOSE and frozenset(cached) != frozenset(dates):
-            print("%sWARNING:%s file dependencies changed: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), files, GetColor()))
+            Warn("file dependencies changed:", files)
 
     return True
 
@@ -1298,7 +1312,7 @@ def GetThirdpartyDir():
         THIRDPARTYDIR = GetThirdpartyBase()+"/android-libs-%s/" % (GetTargetArch())
 
     else:
-        print("%s Unsupported platform: %s" % (ColorText("red", "WARNING:"), target))
+        Warn("Unsupported platform:", target)
         return
 
     if (GetVerbose()):
@@ -1744,11 +1758,10 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
     if not custom_loc and pkgconfig is not None and not libs:
         # pkg-config is all we can do, abort if it wasn't found.
         if pkg in PkgListGet():
-            print("%sWARNING:%s Could not locate pkg-config package %s, excluding from build" % (GetColor("red"), GetColor(), pkgconfig))
+            Warn("Could not locate pkg-config package %s, excluding from build" % (pkgconfig))
             PkgDisable(pkg)
         else:
-            print("%sERROR:%s Could not locate pkg-config package %s, aborting build" % (GetColor("red"), GetColor(), pkgconfig))
-            exit()
+            Error("Could not locate pkg-config package %s, aborting build" % (pkgconfig))
 
     else:
         # Okay, our pkg-config attempts failed. Let's try locating the libs by ourselves.
@@ -1812,14 +1825,12 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
 
         if not have_pkg:
             if custom_loc:
-                print("%sERROR:%s Could not locate thirdparty package %s in specified directory, aborting build" % (GetColor("red"), GetColor(), pkg.lower()))
-                exit()
+                Error("Could not locate thirdparty package %s in specified directory, aborting build" % (pkg.lower()))
             elif pkg in PkgListGet():
-                print("%sWARNING:%s Could not locate thirdparty package %s, excluding from build" % (GetColor("red"), GetColor(), pkg.lower()))
+                Warn("Could not locate thirdparty package %s, excluding from build" % (pkg.lower()))
                 PkgDisable(pkg)
             else:
-                print("%sERROR:%s Could not locate thirdparty package %s, aborting build" % (GetColor("red"), GetColor(), pkg.lower()))
-                exit()
+                Error("Could not locate thirdparty package %s, aborting build" % (pkg.lower()))
 
 ########################################################################
 ##
@@ -2100,7 +2111,7 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         os.environ["PYTHONHOME"] = SDK["PYTHON"]
 
         if sys.version[:3] != ver:
-            print("Warning: running makepanda with Python %s, but building Panda3D with Python %s." % (sys.version[:3], ver))
+            Warn("running makepanda with Python %s, but building Panda3D with Python %s." % (sys.version[:3], ver))
 
     elif CrossCompiling() or (prefer_thirdparty_python and os.path.isdir(os.path.join(GetThirdpartyDir(), "python"))):
         tp_python = os.path.join(GetThirdpartyDir(), "python")
@@ -2743,12 +2754,11 @@ def LibName(opt, name):
             WARNINGS.append(name + " not found.  Skipping Package " + opt)
             if (opt in PkgListGet()):
                 if not PkgSkip(opt):
-                    print("%sWARNING:%s Could not locate thirdparty package %s, excluding from build" % (GetColor("red"), GetColor(), opt.lower()))
+                    Warn("Could not locate thirdparty package %s, excluding from build" % (opt.lower()))
                     PkgDisable(opt)
                 return
             else:
-                print("%sERROR:%s Could not locate thirdparty package %s, aborting build" % (GetColor("red"), GetColor(), opt.lower()))
-                exit()
+                Error("Could not locate thirdparty package %s, aborting build" % (opt.lower()))
     LIBNAMES.append((opt, name))
 
 def DefSymbol(opt, sym, val=""):
@@ -2831,7 +2841,7 @@ def SetupBuildEnvironment(compiler):
 
         returnval = handle.close()
         if returnval != None and returnval != 0:
-            print("%sWARNING:%s %s failed" % (GetColor("red"), GetColor(), cmd))
+            Warn("%s failed" % (cmd))
             SYS_LIB_DIRS += [SDK.get("SYSROOT", "") + "/usr/lib"]
 
         # Now extract the preprocessor's include directories.
@@ -2860,7 +2870,7 @@ def SetupBuildEnvironment(compiler):
                 print("Ignoring non-existent include directory %s" % (line))
 
         if handle.returncode != 0 or not SYS_INC_DIRS:
-            print("%sWARNING:%s %s failed or did not produce the expected result" % (GetColor("red"), GetColor(), cmd))
+            Warn("%s failed or did not produce the expected result" % (cmd))
             sysroot = SDK.get("SYSROOT", "")
             # Add some sensible directories as a fallback.
             SYS_INC_DIRS = [
@@ -3190,6 +3200,48 @@ def WriteResourceFile(basename, **kwargs):
     ConditionalWriteFile(basename, GenerateResourceFile(**kwargs))
     return basename
 
+
+def WriteEmbeddedStringFile(basename, inputs, string_name=None):
+    if os.path.splitext(basename)[1] not in SUFFIX_INC:
+        basename += '.cxx'
+    target = GetOutputDir() + "/tmp/" + basename
+
+    if string_name is None:
+        string_name = os.path.basename(os.path.splitext(target)[0])
+        string_name = string_name.replace('-', '_')
+
+    data = bytearray()
+    for input in inputs:
+        fp = open(input, 'rb')
+
+        # Insert a #line so that we get meaningful compile/assert errors when
+        # the result is inserted by interrogate_module into generated code.
+        if os.path.splitext(input)[1] in SUFFIX_INC:
+            line = '#line 1 "%s"\n' % (input)
+            data += bytearray(line.encode('ascii', 'replace'))
+
+        data += bytearray(fp.read())
+        fp.close()
+
+    data.append(0)
+
+    output = 'extern const char %s[] = {\n' % (string_name)
+
+    i = 0
+    for byte in data:
+        if i == 0:
+            output += ' '
+
+        output += ' 0x%02x,' % (byte)
+        i += 1
+        if i >= 12:
+            output += '\n'
+            i = 0
+
+    output += '\n};\n'
+    ConditionalWriteFile(target, output)
+    return target
+
 ########################################################################
 ##
 ## FindLocation
@@ -3197,6 +3249,8 @@ def WriteResourceFile(basename, **kwargs):
 ########################################################################
 
 ORIG_EXT = {}
+PYABI_SPECIFIC = set()
+WARNED_FILES = set()
 
 def GetOrigExt(x):
     return ORIG_EXT[x]
@@ -3206,15 +3260,37 @@ def SetOrigExt(x, v):
 
 def GetExtensionSuffix():
     if sys.version_info >= (3, 0):
-        suffix = sysconfig.get_config_var('EXT_SUFFIX')
-        if suffix:
-            return suffix
+        import _imp
+        return _imp.extension_suffixes()[0]
+
     target = GetTarget()
     if target == 'windows':
         return '.pyd'
     else:
         return '.so'
 
+def GetPythonABI():
+    soabi = sysconfig.get_config_var('SOABI')
+    if soabi:
+        return soabi
+
+    soabi = 'cpython-%d%d' % (sys.version_info[:2])
+
+    debug_flag = sysconfig.get_config_var('Py_DEBUG')
+    if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag:
+        soabi += 'd'
+
+    malloc_flag = sysconfig.get_config_var('WITH_PYMALLOC')
+    if malloc_flag is None or malloc_flag:
+        soabi += 'm'
+
+    if sys.version_info < (3, 3):
+        usize = sysconfig.get_config_var('Py_UNICODE_SIZE')
+        if (usize is None and sys.maxunicode == 0x10ffff) or usize == 4:
+            soabi += 'u'
+
+    return soabi
+
 def CalcLocation(fn, ipath):
     if fn.startswith("panda3d/") and fn.endswith(".py"):
         return OUTPUTDIR + "/" + fn
@@ -3285,11 +3361,25 @@ def CalcLocation(fn, ipath):
     return fn
 
 
-def FindLocation(fn, ipath):
+def FindLocation(fn, ipath, pyabi=None):
     if (GetLinkAllStatic() and fn.endswith(".dll")):
         fn = fn[:-4] + ".lib"
     loc = CalcLocation(fn, ipath)
     base, ext = os.path.splitext(fn)
+
+    # If this is a target created with PyTargetAdd, we need to make sure it
+    # it put in a Python-version-specific directory.
+    if loc in PYABI_SPECIFIC:
+        if loc.startswith(OUTPUTDIR + "/tmp"):
+            if pyabi is not None:
+                loc = OUTPUTDIR + "/tmp/" + pyabi + loc[len(OUTPUTDIR) + 4:]
+            else:
+                raise RuntimeError("%s is a Python-specific target, use PyTargetAdd instead of TargetAdd" % (fn))
+
+        elif ext != ".pyd" and loc not in WARNED_FILES:
+            WARNED_FILES.add(loc)
+            Warn("file depends on Python but is not in an ABI-specific directory:", loc)
+
     ORIG_EXT[loc] = ext
     return loc
 
@@ -3335,6 +3425,11 @@ def FindLocation(fn, ipath):
 ## be inserted: bison generates an OBJ and a secondary header
 ## file, interrogate generates an IN and a secondary IGATE.OBJ.
 ##
+## PyTargetAdd is a special version for targets that depend on Python.
+## It will create a target for each Python version we are building with,
+## ensuring that builds with different Python versions won't conflict
+## when we build for multiple Python ABIs side-by-side.
+##
 ########################################################################
 
 class Target:
@@ -3343,7 +3438,7 @@ class Target:
 TARGET_LIST = []
 TARGET_TABLE = {}
 
-def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None):
+def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None, pyabi=None):
     if (dummy != 0):
         exit("Syntax error in TargetAdd "+target)
     if ipath is None: ipath = opts
@@ -3351,11 +3446,10 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
     if (type(input) == str): input = [input]
     if (type(dep) == str): dep = [dep]
 
-    if os.path.splitext(target)[1] == '.pyd' and PkgSkip("PYTHON"):
-        # It makes no sense to build Python modules with python disabled.
-        return
+    if target.endswith(".pyd") and not pyabi:
+        raise RuntimeError("Use PyTargetAdd to build .pyd targets")
 
-    full = FindLocation(target, [OUTPUTDIR + "/include"])
+    full = FindLocation(target, [OUTPUTDIR + "/include"], pyabi=pyabi)
 
     if (full not in TARGET_TABLE):
         t = Target()
@@ -3374,7 +3468,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
 
     ipath = [OUTPUTDIR + "/tmp"] + GetListOption(ipath, "DIR:") + [OUTPUTDIR+"/include"]
     for x in input:
-        fullinput = FindLocation(x, ipath)
+        fullinput = FindLocation(x, ipath, pyabi=pyabi)
         t.inputs.append(fullinput)
         # Don't re-link a library or binary if just its dependency dlls have been altered.
         # This should work out fine in most cases, and often reduces recompilation time.
@@ -3413,7 +3507,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
                 t.deps[fulln] = 1
 
     for x in dep:
-        fulldep = FindLocation(x, ipath)
+        fulldep = FindLocation(x, ipath, pyabi=pyabi)
         t.deps[fulldep] = 1
 
     if winrc and GetTarget() == 'windows':
@@ -3430,3 +3524,32 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
 
     if target.endswith(".pz") and not CrossCompiling():
         t.deps[FindLocation("pzip.exe", [])] = 1
+
+    if target.endswith(".in"):
+        # Also add a target to compile the _igate.cxx file into an _igate.obj.
+        outbase = os.path.basename(target)[:-3]
+        woutc = OUTPUTDIR + "/tmp/" + outbase + "_igate.cxx"
+        CxxDependencyCache[woutc] = []
+        PyTargetAdd(outbase + "_igate.obj", opts=opts+['PYTHON','BIGOBJ'], input=woutc, dep=target)
+
+
+def PyTargetAdd(target, opts=[], **kwargs):
+    if PkgSkip("PYTHON"):
+        return
+
+    if 'PYTHON' not in opts:
+        opts = opts + ['PYTHON']
+
+    abi = GetPythonABI()
+
+    MakeDirectory(OUTPUTDIR + "/tmp/" + abi)
+
+    # Mark this target as being a Python-specific target.
+    orig = CalcLocation(target, [OUTPUTDIR + "/include"])
+    PYABI_SPECIFIC.add(orig)
+
+    if orig.startswith(OUTPUTDIR + "/tmp/") and os.path.exists(orig):
+        print("Removing file %s" % (orig))
+        os.unlink(orig)
+
+    TargetAdd(target, opts=opts, pyabi=abi, **kwargs)

+ 1 - 1
makepanda/makewheel.py

@@ -498,7 +498,7 @@ __version__ = '{0}'
     for file in os.listdir(panda3d_dir):
         if file == '__init__.py':
             pass
-        elif file.endswith(ext_suffix) or file.endswith('.py'):
+        elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]):
             source_path = os.path.join(panda3d_dir, file)
 
             if file.endswith('.pyd') and platform.startswith('cygwin'):

+ 5 - 0
makepanda/test_wheel.py

@@ -23,6 +23,11 @@ def test_wheel(wheel, verbose=False):
     else:
         subprocess.call([sys.executable, "-m", "virtualenv", "--clear", envdir])
 
+    # Make sure pip is up-to-date first.
+    if subprocess.call([sys.executable, "-m", "pip", "install", "-U", "pip"]) != 0:
+        shutil.rmtree(envdir)
+        sys.exit(1)
+
     # Install pytest into the environment, as well as our wheel.
     if sys.platform == "win32":
         pip = os.path.join(envdir, "Scripts", "pip.exe")

+ 2 - 1
panda/src/android/android_main.cxx

@@ -19,10 +19,11 @@
 #include "thread.h"
 #include "urlSpec.h"
 
+#include "android_native_app_glue.h"
+
 #include "config_display.h"
 // #define OPENGLES_1 #include "config_androiddisplay.h"
 
-#include <android_native_app_glue.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 

+ 1 - 1
panda/src/audiotraits/fmodAudioSound.cxx

@@ -651,7 +651,7 @@ get_3d_max_distance() const {
  * a balance [pan] function what is the point?
  */
 PN_stdfloat FmodAudioSound::
-get_speaker_mix(AudioManager::SpeakerId speaker) {
+get_speaker_mix(int speaker) {
   ReMutexHolder holder(FmodAudioManager::_lock);
   if (_channel == 0) {
     return 0.0;

+ 2 - 2
panda/src/audiotraits/fmodAudioSound.h

@@ -61,7 +61,7 @@
 #ifndef __FMOD_AUDIO_SOUND_H__
 #define __FMOD_AUDIO_SOUND_H__
 
-#include <pandabase.h>
+#include "pandabase.h"
 
 #include "audioSound.h"
 #include "reMutex.h"
@@ -126,7 +126,7 @@ public:
 
   AudioSound::SoundStatus status() const;
 
-  virtual PN_stdfloat get_speaker_mix(AudioManager::SpeakerId speaker);
+  virtual PN_stdfloat get_speaker_mix(int speaker);
   virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat  sideright);
 
   void set_active(bool active=true);

+ 2 - 1
panda/src/audiotraits/globalMilesManager.h

@@ -17,11 +17,12 @@
 #include "pandabase.h"
 #ifdef HAVE_RAD_MSS //[
 
-#include "mss.h"
 #include "pset.h"
 #include "lightMutex.h"
 #include "lightMutexHolder.h"
 
+#include <mss.h>
+
 #ifndef UINTa
 #define UINTa U32
 #endif

+ 2 - 1
panda/src/audiotraits/milesAudioManager.h

@@ -19,7 +19,6 @@
 #ifdef HAVE_RAD_MSS //[
 
 #include "audioManager.h"
-#include "mss.h"
 #include "pset.h"
 #include "pmap.h"
 #include "pdeque.h"
@@ -30,6 +29,8 @@
 #include "conditionVar.h"
 #include "vector_uchar.h"
 
+#include <mss.h>
+
 class MilesAudioSound;
 
 class EXPCL_MILES_AUDIO MilesAudioManager: public AudioManager {

+ 2 - 1
panda/src/audiotraits/milesAudioSample.h

@@ -20,7 +20,8 @@
 
 #include "milesAudioSound.h"
 #include "milesAudioManager.h"
-#include "mss.h"
+
+#include <mss.h>
 
 /**
  * A sound file, such as a WAV or MP3 file, that is preloaded into memory and

+ 2 - 1
panda/src/audiotraits/milesAudioSequence.h

@@ -19,7 +19,8 @@
 
 #include "milesAudioSound.h"
 #include "milesAudioManager.h"
-#include "mss.h"
+
+#include <mss.h>
 
 /**
  * A MIDI file, preloaded and played from a memory buffer.  MIDI files cannot

+ 2 - 1
panda/src/audiotraits/milesAudioSound.h

@@ -19,7 +19,8 @@
 
 #include "audioSound.h"
 #include "milesAudioManager.h"
-#include "mss.h"
+
+#include <mss.h>
 
 /**
  * The base class for both MilesAudioStream and MilesAudioSample.

+ 2 - 1
panda/src/audiotraits/milesAudioStream.h

@@ -19,7 +19,8 @@
 
 #include "milesAudioSound.h"
 #include "milesAudioManager.h"
-#include "mss.h"
+
+#include <mss.h>
 
 /**
  * This represents a sound file played by the Miles Sound System, similar to

+ 16 - 0
panda/src/audiotraits/openalAudioManager.cxx

@@ -534,6 +534,9 @@ uncache_sound(const Filename &file_name) {
   vfs->resolve_filename(path, get_model_path());
 
   SampleCache::iterator sci = _sample_cache.find(path);
+  if (sci == _sample_cache.end()) {
+    sci = _sample_cache.find(file_name);
+  }
   if (sci != _sample_cache.end()) {
     SoundData *sd = (*sci).second;
     if (sd->_client_count == 0) {
@@ -542,6 +545,19 @@ uncache_sound(const Filename &file_name) {
       delete sd;
     }
   }
+
+  ExpirationQueue::iterator exqi;
+  for (exqi = _expiring_streams.begin(); exqi != _expiring_streams.end();) {
+    SoundData *sd = (SoundData *)(*exqi);
+    if (sd->_client_count == 0) {
+      if (sd->_movie->get_filename() == path ||
+          sd->_movie->get_filename() == file_name) {
+        exqi = _expiring_streams.erase(exqi);
+        continue;
+      }
+    }
+    ++exqi;
+  }
 }
 
 /**

+ 2 - 1
panda/src/awesomium/awWebCore.cxx

@@ -13,7 +13,8 @@
 
 #include "config_awesomium.h"
 #include "awWebCore.h"
-#include "WebCore.h"
+
+#include <WebCore.h>
 
 TypeHandle AwWebCore::_type_handle;
 

+ 3 - 3
panda/src/awesomium/awesomium_includes.h

@@ -14,8 +14,8 @@
 #ifndef _AWESOMIUM_INCLUDES_H_
 #define _AWESOMIUM_INCLUDES_H_
 
-#include "WebCore.h"
-#include "WebView.h"
-#include "WebViewListener.h"
+#include <WebCore.h>
+#include <WebView.h>
+#include <WebViewListener.h>
 
 #endif

+ 15 - 15
panda/src/bullet/bullet_includes.h

@@ -16,23 +16,23 @@
 
 #include "pandabase.h"
 
-#include "btBulletDynamicsCommon.h"
+#include <btBulletDynamicsCommon.h>
 
 #ifndef CPPPARSER
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "BulletCollision/CollisionDispatch/btGhostObject.h"
-#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
-#include "BulletCollision/CollisionShapes/btConvexPointCloudShape.h"
-#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
-#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
-#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
-#include "BulletCollision/Gimpact/btGImpactShape.h"
-#include "BulletDynamics/Character/btKinematicCharacterController.h"
-#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
-#include "BulletSoftBody/btSoftBodyHelpers.h"
-#include "BulletSoftBody/btSoftBodyInternals.h"
-#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
-#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
+#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
+#include <BulletCollision/CollisionDispatch/btGhostObject.h>
+#include <BulletCollision/CollisionDispatch/btManifoldResult.h>
+#include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h>
+#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
+#include <BulletCollision/CollisionShapes/btMinkowskiSumShape.h>
+#include <BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h>
+#include <BulletCollision/Gimpact/btGImpactShape.h>
+#include <BulletDynamics/Character/btKinematicCharacterController.h>
+#include <BulletDynamics/Vehicle/btRaycastVehicle.h>
+#include <BulletSoftBody/btSoftBodyHelpers.h>
+#include <BulletSoftBody/btSoftBodyInternals.h>
+#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h>
+#include <BulletSoftBody/btSoftRigidDynamicsWorld.h>
 #endif
 
 #endif // __BULLET_INCLUDES_H__

+ 5 - 0
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm

@@ -254,6 +254,11 @@ choose_pixel_format(const FrameBufferProperties &properties,
     "Pixel format has " << [format numberOfVirtualScreens] << " virtual screens.\n";
   get_properties(_fbprops, format, 0);
 
+  // Don't enable sRGB unless it was explicitly requested.
+  if (!properties.get_srgb_color()) {
+    _fbprops.set_srgb_color(false);
+  }
+
   // TODO: print out renderer
 
   _context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:_share_context];

+ 0 - 93
panda/src/collada/colladaBindMaterial.cxx

@@ -1,93 +0,0 @@
-/**
- * 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."
- *
- * @file colladaBindMaterial.cxx
- * @author rdb
- * @date 2011-05-26
- */
-
-#include "colladaBindMaterial.h"
-#include "colladaPrimitive.h"
-
-// Collada DOM includes.  No other includes beyond this point.
-#include "pre_collada_include.h"
-#include <dom/domBind_material.h>
-#include <dom/domEffect.h>
-#include <dom/domInstance_effect.h>
-#include <dom/domInstance_material.h>
-#include <dom/domMaterial.h>
-
-#if PANDA_COLLADA_VERSION >= 15
-#include <dom/domFx_profile.h>
-#else
-#include <dom/domFx_profile_abstract.h>
-#define domFx_profile domFx_profile_abstract
-#define domFx_profile_Array domFx_profile_abstract_Array
-#define getFx_profile_array getFx_profile_abstract_array
-#endif
-
-/**
- * Returns the material to be applied to the given primitive, or NULL if there
- * was none bound.
- */
-CPT(RenderState) ColladaBindMaterial::
-get_material(const ColladaPrimitive *prim) const {
-  if (prim == nullptr || _states.count(prim->get_material()) == 0) {
-    return nullptr;
-  }
-  return _states.find(prim->get_material())->second;
-}
-
-/**
- * Returns the bound material with the indicated symbol, or NULL if it was not
- * found.
- */
-CPT(RenderState) ColladaBindMaterial::
-get_material(const std::string &symbol) const {
-  if (_states.count(symbol) == 0) {
-    return nullptr;
-  }
-  return _states.find(symbol)->second;
-}
-
-/**
- * Loads a bind_material object.
- */
-void ColladaBindMaterial::
-load_bind_material(domBind_material &bind_mat) {
-  domInstance_material_Array &mat_instances
-    = bind_mat.getTechnique_common()->getInstance_material_array();
-
-  for (size_t i = 0; i < mat_instances.getCount(); ++i) {
-    load_instance_material(*mat_instances[i]);
-  }
-}
-
-/**
- * Loads an instance_material object.
- */
-void ColladaBindMaterial::
-load_instance_material(domInstance_material &inst) {
-  domMaterialRef mat = daeSafeCast<domMaterial> (inst.getTarget().getElement());
-  nassertv(mat != nullptr);
-
-  domInstance_effectRef einst = mat->getInstance_effect();
-  nassertv(einst != nullptr);
-
-  domInstance_effect::domSetparam_Array &setparams = einst->getSetparam_array();
-
-  domEffectRef effect = daeSafeCast<domEffect>
-    (mat->getInstance_effect()->getUrl().getElement());
-
-  // TODO: read params
-
-  const domFx_profile_Array &profiles = effect->getFx_profile_array();
-  for (size_t i = 0; i < profiles.getCount(); ++i) {
-    // profiles[i]->
-  }
-}

+ 0 - 41
panda/src/collada/colladaBindMaterial.h

@@ -1,41 +0,0 @@
-/**
- * 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."
- *
- * @file colladaBindMaterial.h
- * @author rdb
- * @date 2011-05-25
- */
-
-#ifndef COLLADABINDMATERIAL_H
-#define COLLADABINDMATERIAL_H
-
-#include "config_collada.h"
-#include "renderState.h"
-#include "pmap.h"
-
-class ColladaPrimitive;
-
-class domBind_material;
-class domInstance_material;
-
-/**
- * Class that deals with binding materials to COLLADA geometry.
- */
-class ColladaBindMaterial {
-public:
-  CPT(RenderState) get_material(const ColladaPrimitive *prim) const;
-  CPT(RenderState) get_material(const std::string &symbol) const;
-
-  void load_bind_material(domBind_material &bind_mat);
-  void load_instance_material(domInstance_material &inst);
-
-private:
-  pmap<std::string, CPT(RenderState)> _states;
-};
-
-#endif

+ 0 - 28
panda/src/collada/colladaInput.I

@@ -1,28 +0,0 @@
-/**
- * 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."
- *
- * @file colladaInput.I
- * @author rdb
- * @date 2011-05-23
- */
-
-/**
- * Returns true if this has a <vertices> element as source.
- */
-bool ColladaInput::
-is_vertex_source() const {
-  return (_semantic == "VERTEX");
-}
-
-/**
- * Returns the offset associated with this input.
- */
-unsigned int ColladaInput::
-get_offset() const {
-  return _offset;
-}

+ 0 - 265
panda/src/collada/colladaInput.cxx

@@ -1,265 +0,0 @@
-/**
- * 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."
- *
- * @file colladaInput.cxx
- * @author rdb
- * @date 2011-05-23
- */
-
-#include "colladaInput.h"
-#include "string_utils.h"
-#include "geomVertexArrayFormat.h"
-#include "geomVertexWriter.h"
-
-// Collada DOM includes.  No other includes beyond this point.
-#include "pre_collada_include.h"
-#include <dom/domAccessor.h>
-#include <dom/domP.h>
-#include <dom/domSource.h>
-#include <dom/domVertices.h>
-
-#if PANDA_COLLADA_VERSION >= 15
-#include <dom/domInput_local_offset.h>
-#include <dom/domInput_local.h>
-#else
-#include <dom/domInputLocalOffset.h>
-#include <dom/domInputLocal.h>
-#define domList_of_floats domListOfFloats
-#define domList_of_uints domListOfUInts
-#endif
-
-/**
- * Pretty obvious what this does.
- */
-ColladaInput::
-ColladaInput(const std::string &semantic) :
-  _column_name (nullptr),
-  _semantic (semantic),
-  _offset (0),
-  _have_set (false),
-  _set (0) {
-
-  if (semantic == "POSITION") {
-    _column_name = InternalName::get_vertex();
-    _column_contents = GeomEnums::C_point;
-  } else if (semantic == "COLOR") {
-    _column_name = InternalName::get_color();
-    _column_contents = GeomEnums::C_color;
-  } else if (semantic == "NORMAL") {
-    _column_name = InternalName::get_normal();
-    _column_contents = GeomEnums::C_vector;
-  } else if (semantic == "TEXCOORD") {
-    _column_name = InternalName::get_texcoord();
-    _column_contents = GeomEnums::C_texcoord;
-  } else if (semantic == "TEXBINORMAL") {
-    _column_name = InternalName::get_binormal();
-    _column_contents = GeomEnums::C_vector;
-  } else if (semantic == "TEXTANGENT") {
-    _column_name = InternalName::get_tangent();
-    _column_contents = GeomEnums::C_vector;
-  }
-}
-
-/**
- * Pretty obvious what this does.
- */
-ColladaInput::
-ColladaInput(const std::string &semantic, unsigned int set) :
-  _column_name (nullptr),
-  _semantic (semantic),
-  _offset (0),
-  _have_set (true),
-  _set (set) {
-
-  std::ostringstream setstr;
-  setstr << _set;
-
-  if (semantic == "POSITION") {
-    _column_name = InternalName::get_vertex();
-    _column_contents = GeomEnums::C_point;
-  } else if (semantic == "COLOR") {
-    _column_name = InternalName::get_color();
-    _column_contents = GeomEnums::C_color;
-  } else if (semantic == "NORMAL") {
-    _column_name = InternalName::get_normal();
-    _column_contents = GeomEnums::C_vector;
-  } else if (semantic == "TEXCOORD") {
-    _column_name = InternalName::get_texcoord_name(setstr.str());
-    _column_contents = GeomEnums::C_texcoord;
-  } else if (semantic == "TEXBINORMAL") {
-    _column_name = InternalName::get_binormal_name(setstr.str());
-    _column_contents = GeomEnums::C_vector;
-  } else if (semantic == "TEXTANGENT") {
-    _column_name = InternalName::get_tangent_name(setstr.str());
-    _column_contents = GeomEnums::C_vector;
-  }
-}
-
-/**
- * Returns the ColladaInput object that represents the provided DOM input
- * element.
- */
-ColladaInput *ColladaInput::
-from_dom(domInput_local_offset &input) {
-  // If we already loaded it before, use that.
-  if (input.getUserData() != nullptr) {
-    return (ColladaInput *) input.getUserData();
-  }
-
-  ColladaInput *new_input = new ColladaInput(input.getSemantic(), input.getSet());
-  new_input->_offset = input.getOffset();
-
-  // If this has the VERTEX semantic, it points to a <vertices> element.
-  if (new_input->is_vertex_source()) {
-    domVertices *verts = daeSafeCast<domVertices> (input.getSource().getElement());
-    nassertr(verts != nullptr, nullptr);
-    daeTArray<domInput_localRef> &inputs = verts->getInput_array();
-
-    // Iterate over the <input> elements in <vertices>.
-    for (size_t i = 0; i < inputs.getCount(); ++i) {
-      PT(ColladaInput) vtx_input = ColladaInput::from_dom(*inputs[i]);
-      new_input->_vertex_inputs.push_back(vtx_input);
-    }
-  } else {
-    domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
-    nassertr(source != nullptr, nullptr);
-    new_input->read_data(*source);
-  }
-
-  return new_input;
-}
-
-/**
- * Returns the ColladaInput object that represents the provided DOM input
- * element.
- */
-ColladaInput *ColladaInput::
-from_dom(domInput_local &input) {
-  // If we already loaded it before, use that.
-  if (input.getUserData() != nullptr) {
-    return (ColladaInput *) input.getUserData();
-  }
-
-  ColladaInput *new_input = new ColladaInput(input.getSemantic());
-  new_input->_offset = 0;
-
-  nassertr (!new_input->is_vertex_source(), nullptr);
-
-  domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
-  nassertr(source != nullptr, nullptr);
-  new_input->read_data(*source);
-
-  return new_input;
-}
-
-/**
- * Takes a semantic and source URI, and adds a new column to the format.  If
- * this is a vertex source, adds all of the inputs from the corresponding
- * <vertices> element.  Returns the number of columns added to the format.
- */
-int ColladaInput::
-make_vertex_columns(GeomVertexArrayFormat *format) const {
-
-  if (is_vertex_source()) {
-    int counter = 0;
-    Inputs::const_iterator it;
-    for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
-      counter += (*it)->make_vertex_columns(format);
-    }
-    return counter;
-  }
-
-  nassertr(_column_name != nullptr, 0);
-
-  format->add_column(_column_name, _num_bound_params, GeomEnums::NT_stdfloat, _column_contents);
-  return 1;
-}
-
-/**
- * Reads the data from the source and fills in _data.
- */
-bool ColladaInput::
-read_data(domSource &source) {
-  _data.clear();
-
-  // Get this, get that
-  domFloat_array* float_array = source.getFloat_array();
-  if (float_array == nullptr) {
-    return false;
-  }
-
-  domList_of_floats &floats = float_array->getValue();
-  domAccessor &accessor = *source.getTechnique_common()->getAccessor();
-  domParam_Array &params = accessor.getParam_array();
-
-  // Count the number of params that have a name attribute.
-  _num_bound_params = 0;
-  for (size_t p = 0; p < params.getCount(); ++p) {
-    if (params[p]->getName()) {
-      ++_num_bound_params;
-    }
-  }
-
-  _data.reserve(accessor.getCount());
-
-  domUint pos = accessor.getOffset();
-  for (domUint a = 0; a < accessor.getCount(); ++a) {
-    domUint c = 0;
-    // Yes, the last component defaults to 1 to work around a perspective
-    // divide that Panda3D does internally for points.
-    LVecBase4f v (0, 0, 0, 1);
-    for (domUint p = 0; p < params.getCount(); ++p) {
-      if (params[c]->getName()) {
-        v[c++] = floats[pos + p];
-      }
-    }
-    _data.push_back(v);
-    pos += accessor.getStride();
-  }
-
-  return true;
-}
-
-/**
- * Writes data to the indicated GeomVertexData using the given indices.
- */
-void ColladaInput::
-write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride) const {
-  if (is_vertex_source()) {
-    Inputs::const_iterator it;
-    for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
-      (*it)->write_data(vdata, start_row, p, stride, _offset);
-    }
-
-  } else {
-    write_data(vdata, start_row, p, stride, _offset);
-  }
-}
-
-/**
- * Called internally by the other write_data.
- */
-void ColladaInput::
-write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride, unsigned int offset) const {
-  nassertv(_column_name != nullptr);
-  GeomVertexWriter writer (vdata, _column_name);
-  writer.set_row_unsafe(start_row);
-
-  domList_of_uints &indices = p.getValue();
-
-  // Allocate space for all the rows we're going to write.
-  int min_length = start_row + indices.getCount() / stride;
-  if (vdata->get_num_rows() < min_length) {
-    vdata->unclean_set_num_rows(start_row);
-  }
-
-  for (size_t i = 0; i < indices.getCount(); i += stride) {
-    size_t index = indices[i + offset];
-    writer.add_data4f(_data[index]);
-  }
-}

+ 0 - 77
panda/src/collada/colladaInput.h

@@ -1,77 +0,0 @@
-/**
- * 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."
- *
- * @file colladaInput.h
- * @author rdb
- * @date 2011-05-23
- */
-
-#ifndef COLLADAINPUT_H
-#define COLLADAINPUT_H
-
-#include "config_collada.h"
-#include "referenceCount.h"
-#include "pvector.h"
-#include "pta_LVecBase4.h"
-#include "internalName.h"
-#include "geomEnums.h"
-
-class GeomPrimitive;
-class GeomVertexArrayFormat;
-class GeomVertexData;
-
-#if PANDA_COLLADA_VERSION < 15
-#define domInput_local domInputLocal
-#define domInput_localRef domInputLocalRef
-#define domInput_local_offset domInputLocalOffset
-#define domInput_local_offsetRef domInputLocalOffsetRef
-#endif
-
-class domInput_local;
-class domInput_local_offset;
-class domP;
-class domSource;
-
-/**
- * Class that deals with COLLADA data sources.
- */
-class ColladaInput : public ReferenceCount {
-public:
-  static ColladaInput *from_dom(domInput_local_offset &input);
-  static ColladaInput *from_dom(domInput_local &input);
-
-  int make_vertex_columns(GeomVertexArrayFormat *fmt) const;
-  void write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride) const;
-
-  INLINE bool is_vertex_source() const;
-  INLINE unsigned int get_offset() const;
-
-private:
-  ColladaInput(const std::string &semantic);
-  ColladaInput(const std::string &semantic, unsigned int set);
-  bool read_data(domSource &source);
-  void write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride, unsigned int offset) const;
-
-  typedef pvector<PT(ColladaInput)> Inputs;
-  Inputs _vertex_inputs;
-  PTA_LVecBase4f _data;
-
-  // Only filled in when appropriate.
-  PT(InternalName) _column_name;
-  GeomEnums::Contents _column_contents;
-
-  unsigned int _num_bound_params;
-  unsigned int _offset;
-  std::string _semantic;
-  bool _have_set;
-  unsigned int _set;
-};
-
-#include "colladaInput.I"
-
-#endif

+ 0 - 12
panda/src/collada/colladaLoader.I

@@ -1,12 +0,0 @@
-/**
- * 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."
- *
- * @file colladaLoader.I
- * @author rdb
- * @date 2011-03-16
- */

+ 0 - 549
panda/src/collada/colladaLoader.cxx

@@ -1,549 +0,0 @@
-/**
- * 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."
- *
- * @file colladaLoader.cxx
- * @author Xidram
- * @date 2010-12-21
- */
-
-#include "colladaLoader.h"
-#include "virtualFileSystem.h"
-#include "luse.h"
-#include "string_utils.h"
-#include "geomNode.h"
-#include "geomVertexWriter.h"
-#include "geomTriangles.h"
-#include "lightNode.h"
-#include "lightAttrib.h"
-#include "ambientLight.h"
-#include "directionalLight.h"
-#include "pointLight.h"
-#include "spotlight.h"
-
-#include "colladaBindMaterial.h"
-#include "colladaPrimitive.h"
-
-// Collada DOM includes.  No other includes beyond this point.
-#include "pre_collada_include.h"
-#include <dom/domCOLLADA.h>
-#include <dom/domNode.h>
-#include <dom/domVisual_scene.h>
-#include <dom/domTranslate.h>
-#include <dom/domRotate.h>
-#include <dom/domMatrix.h>
-
-#if PANDA_COLLADA_VERSION >= 15
-#include <dom/domInstance_with_extra.h>
-#else
-#include <dom/domInstanceWithExtra.h>
-#define domInstance_with_extra domInstanceWithExtra
-#define domTargetable_floatRef domTargetableFloatRef
-#endif
-
-#define TOSTRING(x) (x == nullptr ? "" : x)
-
-/**
- *
- */
-ColladaLoader::
-ColladaLoader() :
-  _record (nullptr),
-  _cs (CS_default),
-  _error (false),
-  _root (nullptr),
-  _collada (nullptr) {
-
-  _dae = new DAE;
-}
-
-/**
- *
- */
-ColladaLoader::
-~ColladaLoader() {
-  delete _dae;
-}
-
-/**
- * Reads from the indicated file.
- */
-bool ColladaLoader::
-read(const Filename &filename) {
-  _filename = filename;
-
-  std::string data;
-  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
-
-  if (!vfs->read_file(_filename, data, true)) {
-    collada_cat.error()
-      << "Error reading " << _filename << "\n";
-    _error = true;
-    return false;
-  }
-
-  _collada = _dae->openFromMemory(_filename.to_os_specific(), data.c_str());
-  _error = (_collada == nullptr);
-  return !_error;
-}
-
-/**
- * Converts scene graph structures into a Panda3D scene graph, with _root
- * being the root node.
- */
-void ColladaLoader::
-build_graph() {
-  nassertv(_collada); // read() must be called first
-  nassertv(!_error);  // and have succeeded
-
-  _root = new ModelRoot(_filename.get_basename());
-
-  domCOLLADA::domScene* scene = _collada->getScene();
-  domInstance_with_extra* inst = scene->getInstance_visual_scene();
-  domVisual_scene* vscene = daeSafeCast<domVisual_scene> (inst->getUrl().getElement());
-  if (vscene) {
-    load_visual_scene(*vscene, _root);
-  }
-}
-
-/**
- * Loads a visual scene structure.
- */
-void ColladaLoader::
-load_visual_scene(domVisual_scene& scene, PandaNode *parent) {
-  // If we already loaded it before, instantiate the stored node.
-  if (scene.getUserData() != nullptr) {
-    parent->add_child((PandaNode *) scene.getUserData());
-    return;
-  }
-
-  PT(PandaNode) pnode = new PandaNode(TOSTRING(scene.getName()));
-  scene.setUserData((void *) pnode);
-  parent->add_child(pnode);
-
-  // Load in any tags.
-  domExtra_Array &extras = scene.getExtra_array();
-  for (size_t i = 0; i < extras.getCount(); ++i) {
-    load_tags(*extras[i], pnode);
-  }
-
-  // Now load in the child nodes.
-  domNode_Array &nodes = scene.getNode_array();
-  for (size_t i = 0; i < nodes.getCount(); ++i) {
-    load_node(*nodes[i], pnode);
-  }
-
-  // Apply any lights we've encountered to the visual scene.
-  if (_lights.size() > 0) {
-    CPT(LightAttrib) lattr = DCAST(LightAttrib, LightAttrib::make());
-    pvector<LightNode*>::iterator it;
-    for (it = _lights.begin(); it != _lights.end(); ++it) {
-      lattr = DCAST(LightAttrib, lattr->add_on_light(*it));
-    }
-    pnode->set_state(RenderState::make(lattr));
-
-    _lights.clear();
-  }
-}
-
-/**
- * Loads a COLLADA <node>.
- */
-void ColladaLoader::
-load_node(domNode& node, PandaNode *parent) {
-  // If we already loaded it before, instantiate the stored node.
-  if (node.getUserData() != nullptr) {
-    parent->add_child((PandaNode *) node.getUserData());
-    return;
-  }
-
-  // Create the node.
-  PT(PandaNode) pnode;
-  pnode = new PandaNode(TOSTRING(node.getName()));
-  node.setUserData((void *) pnode);
-  parent->add_child(pnode);
-
-  // Apply the transformation elements in reverse order.
-  LMatrix4f transform (LMatrix4f::ident_mat());
-
-  daeElementRefArray &elements = node.getContents();
-  for (size_t i = elements.getCount(); i > 0; --i) {
-    daeElementRef &elem = elements[i - 1];
-
-    switch (elem->getElementType()) {
-      case COLLADA_TYPE::LOOKAT: {
-        // Didn't test this, but *should* be right.
-        domFloat3x3 &l = (daeSafeCast<domLookat>(elem))->getValue();
-        LPoint3f eye (l[0], l[1], l[2]);
-        LVector3f up (l[6], l[7], l[8]);
-        LVector3f forward = LPoint3f(l[3], l[4], l[5]) - eye;
-        forward.normalize();
-        LVector3f side = forward.cross(up);
-        side.normalize();
-        up = side.cross(forward);
-        LMatrix4f mat (LMatrix4f::ident_mat());
-        mat.set_col(0, side);
-        mat.set_col(1, up);
-        mat.set_col(2, -forward);
-        transform *= mat;
-        transform *= LMatrix4f::translate_mat(-eye);
-        break;
-      }
-      case COLLADA_TYPE::MATRIX: {
-        domFloat4x4 &m = (daeSafeCast<domMatrix>(elem))->getValue();
-        transform *= LMatrix4f(
-          m[0], m[4], m[ 8], m[12],
-          m[1], m[5], m[ 9], m[13],
-          m[2], m[6], m[10], m[14],
-          m[3], m[7], m[11], m[15]);
-        break;
-      }
-      case COLLADA_TYPE::ROTATE: {
-        domFloat4 &r = (daeSafeCast<domRotate>(elem))->getValue();
-        transform *= LMatrix4f::rotate_mat(r[3], LVecBase3f(r[0], r[1], r[2]));
-        break;
-      }
-      case COLLADA_TYPE::SCALE: {
-        domFloat3 &s = (daeSafeCast<domScale>(elem))->getValue();
-        transform *= LMatrix4f::scale_mat(s[0], s[1], s[2]);
-        break;
-      }
-      case COLLADA_TYPE::SKEW:
-        // FIXME: implement skew
-        collada_cat.error() << "<skew> not supported yet\n";
-        break;
-      case COLLADA_TYPE::TRANSLATE: {
-        domFloat3 &t = (daeSafeCast<domTranslate>(elem))->getValue();
-        transform *= LMatrix4f::translate_mat(t[0], t[1], t[2]);
-        break;
-      }
-    }
-  }
-  // TODO: convert coordinate systems transform *= LMatrix4f::convert_mat(XXX,
-  // _cs);
-
-  // If there's a transform, set it.
-  if (transform != LMatrix4f::ident_mat()) {
-    pnode->set_transform(TransformState::make_mat(transform));
-  }
-
-  // See if this node instantiates any cameras.
-  domInstance_camera_Array &caminst = node.getInstance_camera_array();
-  for (size_t i = 0; i < caminst.getCount(); ++i) {
-    domCamera* target = daeSafeCast<domCamera> (caminst[i]->getUrl().getElement());
-    load_camera(*target, pnode);
-  }
-
-  // See if this node instantiates any controllers.
-  domInstance_controller_Array &ctrlinst = node.getInstance_controller_array();
-  for (size_t i = 0; i < ctrlinst.getCount(); ++i) {
-    domController* target = daeSafeCast<domController> (ctrlinst[i]->getUrl().getElement());
-    // TODO: implement controllers.  For now, let's just read the geometry
-    if (target->getSkin() != nullptr) {
-      domGeometry* geom = daeSafeCast<domGeometry> (target->getSkin()->getSource().getElement());
-      // TODO load_geometry(*geom, ctrlinst[i]->getBind_material(), pnode);
-    }
-  }
-
-  // See if this node instantiates any geoms.
-  domInstance_geometry_Array &ginst = node.getInstance_geometry_array();
-  for (size_t i = 0; i < ginst.getCount(); ++i) {
-    load_instance_geometry(*ginst[i], pnode);
-  }
-
-  // See if this node instantiates any lights.
-  domInstance_light_Array &linst = node.getInstance_light_array();
-  for (size_t i = 0; i < linst.getCount(); ++i) {
-    domLight* target = daeSafeCast<domLight> (linst[i]->getUrl().getElement());
-    load_light(*target, pnode);
-  }
-
-  // And instantiate any <instance_nodes> elements.
-  domInstance_node_Array &ninst = node.getInstance_node_array();
-  for (size_t i = 0; i < ninst.getCount(); ++i) {
-    domNode* target = daeSafeCast<domNode> (ninst[i]->getUrl().getElement());
-    load_node(*target, pnode);
-  }
-
-  // Now load in the child nodes.
-  domNode_Array &nodes = node.getNode_array();
-  for (size_t i = 0; i < nodes.getCount(); ++i) {
-    load_node(*nodes[i], pnode);
-  }
-
-  // Load in any tags.
-  domExtra_Array &extras = node.getExtra_array();
-  for (size_t i = 0; i < extras.getCount(); ++i) {
-    load_tags(*extras[i], pnode);
-    // TODO: load SI_Visibility under XSI profile TODO: support
-    // OpenSceneGraph's switch nodes
-  }
-}
-
-/**
- * Loads tags specified in an <extra> element.
- */
-void ColladaLoader::
-load_tags(domExtra &extra, PandaNode *node) {
-  domTechnique_Array &techniques = extra.getTechnique_array();
-
-  for (size_t t = 0; t < techniques.getCount(); ++t) {
-    if (cmp_nocase(techniques[t]->getProfile(), "PANDA3D") == 0) {
-      const daeElementRefArray &children = techniques[t]->getChildren();
-
-      for (size_t c = 0; c < children.getCount(); ++c) {
-        daeElement &child = *children[c];
-
-        if (cmp_nocase(child.getElementName(), "tag") == 0) {
-          const std::string &name = child.getAttribute("name");
-          if (name.size() > 0) {
-            node->set_tag(name, child.getCharData());
-          } else {
-            collada_cat.warning() << "Ignoring <tag> without name attribute\n";
-          }
-        } else if (cmp_nocase(child.getElementName(), "param") == 0) {
-          collada_cat.error() <<
-            "Unknown <param> attribute in PANDA3D technique. "
-            "Did you mean to use <tag> instead?\n";
-        }
-      }
-    }
-  }
-}
-
-/**
- * Loads a COLLADA <camera> as a Camera object.
- */
-void ColladaLoader::
-load_camera(domCamera &cam, PandaNode *parent) {
-  // If we already loaded it before, instantiate the stored node.
-  if (cam.getUserData() != nullptr) {
-    parent->add_child((PandaNode *) cam.getUserData());
-    return;
-  }
-
-  // TODO
-}
-
-/**
- * Loads a COLLADA <instance_geometry> as a GeomNode object.
- */
-void ColladaLoader::
-load_instance_geometry(domInstance_geometry &inst, PandaNode *parent) {
-  // If we already loaded it before, instantiate the stored node.
-  if (inst.getUserData() != nullptr) {
-    parent->add_child((PandaNode *) inst.getUserData());
-    return;
-  }
-
-  domGeometry* geom = daeSafeCast<domGeometry> (inst.getUrl().getElement());
-  nassertv(geom != nullptr);
-
-  // Create the node.
-  PT(GeomNode) gnode = new GeomNode(TOSTRING(geom->getName()));
-  inst.setUserData((void *) gnode);
-  parent->add_child(gnode);
-
-  domBind_materialRef bind_mat = inst.getBind_material();
-  ColladaBindMaterial cbm;
-  if (bind_mat != nullptr) {
-    cbm.load_bind_material(*bind_mat);
-  }
-
-  load_geometry(*geom, gnode, cbm);
-
-  // Load in any tags.
-  domExtra_Array &extras = geom->getExtra_array();
-  for (size_t i = 0; i < extras.getCount(); ++i) {
-    load_tags(*extras[i], gnode);
-  }
-}
-
-/**
- * Loads a COLLADA <geometry> and adds the primitives to the given GeomNode
- * object.
- */
-void ColladaLoader::
-load_geometry(domGeometry &geom, GeomNode *gnode, ColladaBindMaterial &bind_mat) {
-  domMesh* mesh = geom.getMesh();
-  if (mesh == nullptr) {
-    // TODO: support non-mesh geometry.
-    return;
-  }
-
-  // TODO: support other than just triangles.
-  domLines_Array &lines_array = mesh->getLines_array();
-  for (size_t i = 0; i < lines_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*lines_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domLinestrips_Array &linestrips_array = mesh->getLinestrips_array();
-  for (size_t i = 0; i < linestrips_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*linestrips_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domPolygons_Array &polygons_array = mesh->getPolygons_array();
-  for (size_t i = 0; i < polygons_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*polygons_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domPolylist_Array &polylist_array = mesh->getPolylist_array();
-  for (size_t i = 0; i < polylist_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*polylist_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domTriangles_Array &triangles_array = mesh->getTriangles_array();
-  for (size_t i = 0; i < triangles_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*triangles_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domTrifans_Array &trifans_array = mesh->getTrifans_array();
-  for (size_t i = 0; i < trifans_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*trifans_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-
-  domTristrips_Array &tristrips_array = mesh->getTristrips_array();
-  for (size_t i = 0; i < tristrips_array.getCount(); ++i) {
-    PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*tristrips_array[i]);
-    if (prim != nullptr) {
-      gnode->add_geom(prim->get_geom());
-    }
-  }
-}
-
-/**
- * Loads a COLLADA <light> as a LightNode object.
- */
-void ColladaLoader::
-load_light(domLight &light, PandaNode *parent) {
-  // If we already loaded it before, instantiate the stored node.
-  if (light.getUserData() != nullptr) {
-    parent->add_child((PandaNode *) light.getUserData());
-    return;
-  }
-
-  PT(LightNode) lnode;
-  domLight::domTechnique_common &tc = *light.getTechnique_common();
-
-  // Check for an ambient light.
-  domLight::domTechnique_common::domAmbientRef ambient = tc.getAmbient();
-  if (ambient != nullptr) {
-    PT(AmbientLight) alight = new AmbientLight(TOSTRING(light.getName()));
-    lnode = DCAST(LightNode, alight);
-
-    domFloat3 &color = ambient->getColor()->getValue();
-    alight->set_color(LColor(color[0], color[1], color[2], 1.0));
-  }
-
-  // Check for a directional light.
-  domLight::domTechnique_common::domDirectionalRef directional = tc.getDirectional();
-  if (directional != nullptr) {
-    PT(DirectionalLight) dlight = new DirectionalLight(TOSTRING(light.getName()));
-    lnode = DCAST(LightNode, dlight);
-
-    domFloat3 &color = directional->getColor()->getValue();
-    dlight->set_color(LColor(color[0], color[1], color[2], 1.0));
-    dlight->set_direction(LVector3f(0, 0, -1));
-  }
-
-  // Check for a point light.
-  domLight::domTechnique_common::domPointRef point = tc.getPoint();
-  if (point != nullptr) {
-    PT(PointLight) plight = new PointLight(TOSTRING(light.getName()));
-    lnode = DCAST(LightNode, plight);
-
-    domFloat3 &color = point->getColor()->getValue();
-    plight->set_color(LColor(color[0], color[1], color[2], 1.0));
-
-    LVecBase3f atten (1.0f, 0.0f, 0.0f);
-    domTargetable_floatRef fval = point->getConstant_attenuation();
-    if (fval != nullptr) {
-      atten[0] = fval->getValue();
-    }
-    fval = point->getLinear_attenuation();
-    if (fval != nullptr) {
-      atten[1] = fval->getValue();
-    }
-    fval = point->getQuadratic_attenuation();
-    if (fval != nullptr) {
-      atten[2] = fval->getValue();
-    }
-
-    plight->set_attenuation(atten);
-  }
-
-  // Check for a spot light.
-  domLight::domTechnique_common::domSpotRef spot = tc.getSpot();
-  if (spot != nullptr) {
-    PT(Spotlight) slight = new Spotlight(TOSTRING(light.getName()));
-    lnode = DCAST(LightNode, slight);
-
-    domFloat3 &color = spot->getColor()->getValue();
-    slight->set_color(LColor(color[0], color[1], color[2], 1.0));
-
-    LVecBase3f atten (1.0f, 0.0f, 0.0f);
-    domTargetable_floatRef fval = spot->getConstant_attenuation();
-    if (fval != nullptr) {
-      atten[0] = fval->getValue();
-    }
-    fval = spot->getLinear_attenuation();
-    if (fval != nullptr) {
-      atten[1] = fval->getValue();
-    }
-    fval = spot->getQuadratic_attenuation();
-    if (fval != nullptr) {
-      atten[2] = fval->getValue();
-    }
-
-    slight->set_attenuation(atten);
-
-    fval = spot->getFalloff_angle();
-    if (fval != nullptr) {
-      slight->get_lens()->set_fov(fval->getValue());
-    } else {
-      slight->get_lens()->set_fov(180.0f);
-    }
-
-    fval = spot->getFalloff_exponent();
-    if (fval != nullptr) {
-      slight->set_exponent(fval->getValue());
-    } else {
-      slight->set_exponent(0.0f);
-    }
-  }
-
-  if (lnode == nullptr) {
-    return;
-  }
-  parent->add_child(lnode);
-  _lights.push_back(lnode);
-  light.setUserData((void*) lnode);
-
-  // Load in any tags.
-  domExtra_Array &extras = light.getExtra_array();
-  for (size_t i = 0; i < extras.getCount(); ++i) {
-    load_tags(*extras[i], lnode);
-  }
-}

+ 0 - 76
panda/src/collada/colladaLoader.h

@@ -1,76 +0,0 @@
-/**
- * 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."
- *
- * @file colladaLoader.h
- * @author Xidram
- * @date 2010-12-21
- */
-
-#ifndef COLLADALOADER_H
-#define COLLADALOADER_H
-
-#include "pandabase.h"
-#include "config_collada.h"
-#include "typedReferenceCount.h"
-#include "pandaNode.h"
-#include "modelRoot.h"
-#include "pvector.h"
-#include "pta_LVecBase4.h"
-
-class ColladaBindMaterial;
-class BamCacheRecord;
-class GeomNode;
-class LightNode;
-
-class domBind_material;
-class domCOLLADA;
-class domNode;
-class domVisual_scene;
-class domExtra;
-class domGeometry;
-class domInstance_geometry;
-class domLight;
-class domCamera;
-class domSource;
-class DAE;
-
-/**
- * Object that interfaces with the COLLADA DOM library and loads the COLLADA
- * structures into Panda nodes.
- */
-class ColladaLoader {
-public:
-  ColladaLoader();
-  virtual ~ColladaLoader();
-
-  bool _error;
-  PT(ModelRoot) _root;
-  BamCacheRecord *_record;
-  CoordinateSystem _cs;
-  Filename _filename;
-
-  bool read(const Filename &filename);
-  void build_graph();
-
-private:
-  const domCOLLADA* _collada;
-  DAE* _dae;
-  pvector<LightNode*> _lights;
-
-  void load_visual_scene(domVisual_scene &scene, PandaNode *parent);
-  void load_node(domNode &node, PandaNode *parent);
-  void load_tags(domExtra &extra, PandaNode *node);
-  void load_camera(domCamera &cam, PandaNode *parent);
-  void load_instance_geometry(domInstance_geometry &inst, PandaNode *parent);
-  void load_geometry(domGeometry &geom, GeomNode *parent, ColladaBindMaterial &bind_mat);
-  void load_light(domLight &light, PandaNode *parent);
-};
-
-#include "colladaLoader.I"
-
-#endif

+ 0 - 40
panda/src/collada/colladaPrimitive.I

@@ -1,40 +0,0 @@
-/**
- * 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."
- *
- * @file colladaPrimitive.I
- * @author rdb
- * @date 2011-05-23
- */
-
-/**
- * Adds a new ColladaInput to this primitive.
- */
-INLINE void ColladaPrimitive::
-add_input(ColladaInput *input) {
-  if (input->get_offset() >= _stride) {
-    _stride = input->get_offset() + 1;
-  }
-  _inputs.push_back(input);
-}
-
-/**
- * Returns the Geom associated with this primitive.
- */
-INLINE PT(Geom) ColladaPrimitive::
-get_geom() const {
-  return _geom;
-}
-
-/**
- * Returns the name of this primitive's material, or the empty string if none
- * was assigned.
- */
-INLINE const std::string &ColladaPrimitive::
-get_material() const {
-  return _material;
-}

+ 0 - 293
panda/src/collada/colladaPrimitive.cxx

@@ -1,293 +0,0 @@
-/**
- * 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."
- *
- * @file colladaPrimitive.cxx
- * @author rdb
- * @date 2011-05-23
- */
-
-#include "colladaPrimitive.h"
-#include "geomLines.h"
-#include "geomLinestrips.h"
-#include "geomTriangles.h"
-#include "geomTrifans.h"
-#include "geomTristrips.h"
-
-// Collada DOM includes.  No other includes beyond this point.
-#include "pre_collada_include.h"
-#include <dom/domLines.h>
-#include <dom/domLinestrips.h>
-#include <dom/domPolygons.h>
-#include <dom/domPolylist.h>
-#include <dom/domTriangles.h>
-#include <dom/domTrifans.h>
-#include <dom/domTristrips.h>
-
-#if PANDA_COLLADA_VERSION < 15
-#define domInput_local_offsetRef domInputLocalOffsetRef
-#endif
-
-/**
- * Why do I even bother documenting the simplest of constructors?  A private
- * one at that.
- */
-ColladaPrimitive::
-ColladaPrimitive(GeomPrimitive *prim, daeTArray<domInput_local_offsetRef> &inputs)
-  : _stride (1), _gprim (prim) {
-
-  PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat;
-
-  // Add the inputs one by one.
-  for (size_t in = 0; in < inputs.getCount(); ++in) {
-    PT(ColladaInput) input = ColladaInput::from_dom(*inputs[in]);
-    add_input(input);
-
-    input->make_vertex_columns(aformat);
-  }
-
-  // Create the vertex data.
-  PT(GeomVertexFormat) format = new GeomVertexFormat();
-  format->add_array(aformat);
-  _vdata = new GeomVertexData("", GeomVertexFormat::register_format(format), GeomEnums::UH_static);
-  _geom = new Geom(_vdata);
-  _geom->add_primitive(_gprim);
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domLines &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomLines(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  domPRef p = prim.getP();
-  if (p != nullptr) {
-    new_prim->load_primitive(*p);
-  }
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domLinestrips &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomLinestrips(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  new_prim->load_primitives(prim.getP_array());
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domPolygons &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  // We use trifans to represent polygons, seems to be easiest.  I tried using
-  // tristrips instead, but for some reason, this resulted in a few flipped
-  // polygons.  Weird.
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  new_prim->load_primitives(prim.getP_array());
-
-  if (prim.getPh_array().getCount() > 0) {
-    collada_cat.error()
-      << "Polygons with holes are not supported!\n";
-  }
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domPolylist &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  // We use trifans to represent polygons, seems to be easiest.  I tried using
-  // tristrips instead, but for some reason, this resulted in a few flipped
-  // polygons.  Weird.
-  PT(GeomPrimitive) gprim = new GeomTrifans(GeomEnums::UH_static);
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(gprim, prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  domPRef p = prim.getP();
-  domPolylist::domVcountRef vcounts = prim.getVcount();
-  if (p == nullptr || vcounts == nullptr) {
-    return new_prim;
-  }
-
-  new_prim->write_data(new_prim->_vdata, 0, *p);
-
-  daeTArray<domUint> &values = vcounts->getValue();
-  for (size_t i = 0; i < values.getCount(); ++i) {
-    unsigned int vcount = values[i];
-    gprim->add_next_vertices(vcount);
-    gprim->close_primitive();
-  }
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domTriangles &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomTriangles(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  domPRef p = prim.getP();
-  if (p != nullptr) {
-    new_prim->load_primitive(*p);
-  }
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domTrifans &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  new_prim->load_primitives(prim.getP_array());
-
-  return new_prim;
-}
-
-/**
- * Returns the ColladaPrimitive object that represents the provided DOM input
- * element.
- */
-ColladaPrimitive *ColladaPrimitive::
-from_dom(domTristrips &prim) {
-  // If we already loaded it before, use that.
-  if (prim.getUserData() != nullptr) {
-    return (ColladaPrimitive *) prim.getUserData();
-  }
-
-  ColladaPrimitive *new_prim =
-    new ColladaPrimitive(new GeomTristrips(GeomEnums::UH_static),
-                         prim.getInput_array());
-  new_prim->_material = prim.getMaterial();
-
-  prim.setUserData(new_prim);
-
-  new_prim->load_primitives(prim.getP_array());
-
-  return new_prim;
-}
-
-/**
- * Writes the vertex data to the GeomVertexData.  Returns the number of rows
- * written.
- */
-unsigned int ColladaPrimitive::
-write_data(GeomVertexData *vdata, int start_row, domP &p) {
-  unsigned int num_vertices = p.getValue().getCount() / _stride;
-
-  Inputs::iterator it;
-  for (it = _inputs.begin(); it != _inputs.end(); ++it) {
-    (*it)->write_data(vdata, start_row, p, _stride);
-  }
-
-  return num_vertices;
-}
-
-/**
- * Adds the given indices to the primitive, and writes the relevant data to
- * the geom.
- */
-void ColladaPrimitive::
-load_primitive(domP &p) {
-  _gprim->add_next_vertices(write_data(_vdata, 0, p));
-  _gprim->close_primitive();
-}
-
-/**
- * Adds the given indices to the primitive, and writes the relevant data to
- * the geom.
- */
-void ColladaPrimitive::
-load_primitives(domP_Array &p_array) {
-  int start_row = 0;
-
-  for (size_t i = 0; i < p_array.getCount(); ++i) {
-    unsigned int num_vertices = write_data(_vdata, start_row, *p_array[i]);
-    _gprim->add_next_vertices(num_vertices);
-    _gprim->close_primitive();
-    start_row += num_vertices;
-  }
-}

+ 0 - 71
panda/src/collada/colladaPrimitive.h

@@ -1,71 +0,0 @@
-/**
- * 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."
- *
- * @file colladaPrimitive.h
- * @author rdb
- * @date 2011-05-23
- */
-
-#ifndef COLLADAPRIMITIVE_H
-#define COLLADAPRIMITIVE_H
-
-#include "config_collada.h"
-#include "referenceCount.h"
-#include "geomVertexData.h"
-#include "geom.h"
-#include "geomPrimitive.h"
-
-#include "colladaInput.h"
-
-class domP;
-class domLines;
-class domLinestrips;
-class domPolygons;
-class domPolylist;
-class domTriangles;
-class domTrifans;
-class domTristrips;
-
-/**
- * Class that deals with COLLADA primitive structures, such as <triangles> and
- * <polylist>.
- */
-class ColladaPrimitive : public ReferenceCount {
-public:
-  static ColladaPrimitive *from_dom(domLines &lines);
-  static ColladaPrimitive *from_dom(domLinestrips &linestrips);
-  static ColladaPrimitive *from_dom(domPolygons &polygons);
-  static ColladaPrimitive *from_dom(domPolylist &polylist);
-  static ColladaPrimitive *from_dom(domTriangles &triangles);
-  static ColladaPrimitive *from_dom(domTrifans &trifans);
-  static ColladaPrimitive *from_dom(domTristrips &tristrips);
-
-  unsigned int write_data(GeomVertexData *vdata, int start_row, domP &p);
-
-  INLINE PT(Geom) get_geom() const;
-  INLINE const std::string &get_material() const;
-
-private:
-  ColladaPrimitive(GeomPrimitive *prim, daeTArray<daeSmartRef<domInput_local_offset> > &inputs);
-  void load_primitive(domP &p);
-  void load_primitives(daeTArray<daeSmartRef<domP> > &p_array);
-  INLINE void add_input(ColladaInput *input);
-
-  typedef pvector<PT(ColladaInput)> Inputs;
-  Inputs _inputs;
-
-  unsigned int _stride;
-  PT(Geom) _geom;
-  PT(GeomVertexData) _vdata;
-  PT(GeomPrimitive) _gprim;
-  std::string _material;
-};
-
-#include "colladaPrimitive.I"
-
-#endif

+ 0 - 87
panda/src/collada/config_collada.cxx

@@ -1,87 +0,0 @@
-/**
- * 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."
- *
- * @file config_collada.cxx
- * @author Xidram
- * @date 2010-12-21
- */
-
-#include "config_collada.h"
-
-#include "dconfig.h"
-#include "loaderFileTypeDae.h"
-#include "loaderFileTypeRegistry.h"
-
-#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_COLLADA)
-  #error Buildsystem error: BUILDING_COLLADA not defined
-#endif
-
-ConfigureDef(config_collada);
-NotifyCategoryDef(collada, "");
-
-ConfigVariableBool collada_flatten
-("collada-flatten", false,
- PRC_DESC("This is normally true to flatten out useless nodes after loading "
-          "a collada file.  Set it false if you want to see the complete "
-          "and true hierarchy as specified in the file (although the "
-          "extra nodes may have a small impact on render performance)."));
-
-ConfigVariableDouble collada_flatten_radius
-("collada-flatten-radius", 0.0,
- PRC_DESC("This specifies the minimum cull radius in the egg file.  Nodes "
-          "whose bounding volume is smaller than this radius will be "
-          "flattened tighter than nodes larger than this radius, to "
-          "reduce the node count even further.  The idea is that small "
-          "objects will not need to have their individual components "
-          "culled separately, but large environments should.  This allows "
-          "the user to specify what should be considered \"small\".  Set "
-          "it to 0.0 to disable this feature."));
-
-ConfigVariableBool collada_unify
-("collada-unify", true,
- PRC_DESC("When this is true, then in addition to flattening the scene graph "
-          "nodes, the collada loader will also combine as many Geoms as "
-          "possible within "
-          "a given node into a single Geom.  This has theoretical performance "
-          "benefits, especially on higher-end graphics cards, but it also "
-          "slightly slows down collada loading."));
-
-ConfigVariableBool collada_combine_geoms
-("collada-combine-geoms", false,
- PRC_DESC("Set this true to combine sibling GeomNodes into a single GeomNode, "
-          "when possible."));
-
-ConfigVariableBool collada_accept_errors
-("collada-accept-errors", true,
- PRC_DESC("When this is true, certain kinds of recoverable errors (not syntax "
-          "errors) in a collada file will be allowed and ignored when a "
-          "collada file is loaded.  When it is false, only perfectly pristine "
-          "collada files may be loaded."));
-
-ConfigureFn(config_collada) {
-  init_libcollada();
-}
-
-/**
- * Initializes the library.  This must be called at least once before any of
- * the functions or classes in this library can be used.  Normally it will be
- * called by the static initializers and need not be called explicitly, but
- * special cases exist.
- */
-void
-init_libcollada() {
-  static bool initialized = false;
-  if (initialized) {
-    return;
-  }
-  initialized = true;
-
-  LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_global_ptr();
-
-  reg->register_type(new LoaderFileTypeDae);
-}

+ 0 - 36
panda/src/collada/config_collada.h

@@ -1,36 +0,0 @@
-/**
- * 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."
- *
- * @file config_collada.h
- * @author Xidram
- * @date 2010-12-21
- */
-
-#ifndef CONFIG_COLLADA_H
-#define CONFIG_COLLADA_H
-
-#include "pandabase.h"
-
-#include "notifyCategoryProxy.h"
-#include "dconfig.h"
-
-template<class T> class daeTArray;
-template<class T> class daeSmartRef;
-
-ConfigureDecl(config_collada, EXPCL_COLLADA, EXPTP_COLLADA);
-NotifyCategoryDecl(collada, EXPCL_COLLADA, EXPTP_COLLADA);
-
-extern EXPCL_COLLADA ConfigVariableBool collada_flatten;
-extern EXPCL_COLLADA ConfigVariableBool collada_unify;
-extern EXPCL_COLLADA ConfigVariableDouble collada_flatten_radius;
-extern EXPCL_COLLADA ConfigVariableBool collada_combine_geoms;
-extern EXPCL_COLLADA ConfigVariableBool collada_accept_errors;
-
-extern EXPCL_COLLADA void init_libcollada();
-
-#endif

+ 0 - 92
panda/src/collada/load_collada_file.cxx

@@ -1,92 +0,0 @@
-/**
- * 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."
- *
- * @file load_collada_file.cxx
- * @author rdb
- * @date 2011-03-16
- */
-
-#include "load_collada_file.h"
-#include "colladaLoader.h"
-#include "config_collada.h"
-#include "sceneGraphReducer.h"
-#include "virtualFileSystem.h"
-#include "config_putil.h"
-#include "bamCacheRecord.h"
-
-static PT(PandaNode)
-load_from_loader(ColladaLoader &loader) {
-  loader.build_graph();
-
-  if (loader._error && !collada_accept_errors) {
-    collada_cat.error()
-      << "Errors in collada file.\n";
-    return nullptr;
-  }
-
-  if (loader._root != nullptr && collada_flatten) {
-    SceneGraphReducer gr;
-
-    int combine_siblings_bits = 0;
-    if (collada_combine_geoms) {
-      combine_siblings_bits |= SceneGraphReducer::CS_geom_node;
-    }
-    if (collada_flatten_radius > 0.0) {
-      combine_siblings_bits |= SceneGraphReducer::CS_within_radius;
-      gr.set_combine_radius(collada_flatten_radius);
-    }
-
-    int num_reduced = gr.flatten(loader._root, combine_siblings_bits);
-    collada_cat.info() << "Flattened " << num_reduced << " nodes.\n";
-
-    if (collada_unify) {
-      // We want to premunge before unifying, since otherwise we risk
-      // needlessly duplicating vertices.
-      if (premunge_data) {
-        gr.premunge(loader._root, RenderState::make_empty());
-      }
-      gr.collect_vertex_data(loader._root);
-      gr.unify(loader._root, true);
-      if (collada_cat.is_debug()) {
-        collada_cat.debug() << "Unified.\n";
-      }
-    }
-  }
-
-  return DCAST(ModelRoot, loader._root);
-}
-
-/**
- * A convenience function.  Loads up the indicated dae file, and returns the
- * root of a scene graph.  Returns NULL if the file cannot be read for some
- * reason.  Does not search along the model path for the filename first.
- */
-PT(PandaNode)
-load_collada_file(const Filename &filename, CoordinateSystem cs,
-                  BamCacheRecord *record) {
-
-  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
-
-  if (record != nullptr) {
-    record->add_dependent_file(filename);
-  }
-
-  ColladaLoader loader;
-  loader._filename = filename;
-  loader._cs = cs;
-  loader._record = record;
-
-  collada_cat.info()
-    << "Reading " << filename << "\n";
-
-  if (!loader.read(filename)) {
-    return nullptr;
-  }
-
-  return load_from_loader(loader);
-}

+ 0 - 36
panda/src/collada/load_collada_file.h

@@ -1,36 +0,0 @@
-/**
- * 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."
- *
- * @file load_collada_file.h
- * @author rdb
- * @date 2011-03-16
- */
-
-#ifndef LOAD_COLLADA_FILE_H
-#define LOAD_COLLADA_FILE_H
-
-#include "pandabase.h"
-
-#include "pandaNode.h"
-#include "filename.h"
-#include "coordinateSystem.h"
-
-class BamCacheRecord;
-
-BEGIN_PUBLISH
-/**
- * A convenience function; the primary interface to this package.  Loads up
- * the indicated DAE file, and returns the root of a scene graph.  Returns
- * NULL if the file cannot be read for some reason.
- */
-EXPCL_COLLADA PT(PandaNode)
-load_collada_file(const Filename &filename, CoordinateSystem cs = CS_default,
-                  BamCacheRecord *record = nullptr);
-END_PUBLISH
-
-#endif

+ 0 - 74
panda/src/collada/loaderFileTypeDae.cxx

@@ -1,74 +0,0 @@
-/**
- * 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."
- *
- * @file loaderFileTypeDae.cxx
- * @author rdb
- * @date 2009-08-23
- */
-
-#include "loaderFileTypeDae.h"
-#include "load_collada_file.h"
-
-TypeHandle LoaderFileTypeDae::_type_handle;
-
-/**
- *
- */
-LoaderFileTypeDae::
-LoaderFileTypeDae() {
-}
-
-/**
- *
- */
-std::string LoaderFileTypeDae::
-get_name() const {
-#if PANDA_COLLADA_VERSION == 14
-  return "COLLADA 1.4";
-#elif PANDA_COLLADA_VERSION == 15
-  return "COLLADA 1.5";
-#else
-  return "COLLADA";
-#endif
-}
-
-/**
- *
- */
-std::string LoaderFileTypeDae::
-get_extension() const {
-  return "dae";
-}
-
-/**
- * Returns a space-separated list of extension, in addition to the one
- * returned by get_extension(), that are recognized by this loader.
- */
-std::string LoaderFileTypeDae::
-get_additional_extensions() const {
-  return "zae";
-}
-
-/**
- * Returns true if this file type can transparently load compressed files
- * (with a .pz or .gz extension), false otherwise.
- */
-bool LoaderFileTypeDae::
-supports_compressed() const {
-  return true;
-}
-
-/**
- *
- */
-PT(PandaNode) LoaderFileTypeDae::
-load_file(const Filename &path, const LoaderOptions &,
-          BamCacheRecord *record) const {
-  PT(PandaNode) result = load_collada_file(path, CS_default, record);
-  return result;
-}

+ 0 - 54
panda/src/collada/loaderFileTypeDae.h

@@ -1,54 +0,0 @@
-/**
- * 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."
- *
- * @file loaderFileTypeDae.h
- * @author rdb
- * @date 2009-08-23
- */
-
-#ifndef LOADERFILETYPEDAE_H
-#define LOADERFILETYPEDAE_H
-
-#include "pandabase.h"
-
-#include "loaderFileType.h"
-
-/**
- * This defines the Loader interface to read Dae files.
- */
-class EXPCL_COLLADA LoaderFileTypeDae : public LoaderFileType {
-public:
-  LoaderFileTypeDae();
-
-  virtual std::string get_name() const;
-  virtual std::string get_extension() const;
-  virtual std::string get_additional_extensions() const;
-  virtual bool supports_compressed() const;
-
-  virtual PT(PandaNode) load_file(const Filename &path, const LoaderOptions &options,
-                                  BamCacheRecord *record) const;
-
-public:
-  static TypeHandle get_class_type() {
-    return _type_handle;
-  }
-  static void init_type() {
-    LoaderFileType::init_type();
-    register_type(_type_handle, "LoaderFileTypeDae",
-                  LoaderFileType::get_class_type());
-  }
-  virtual TypeHandle get_type() const {
-    return get_class_type();
-  }
-  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
-
-private:
-  static TypeHandle _type_handle;
-};
-
-#endif

+ 0 - 3
panda/src/collada/p3collada_composite1.cxx

@@ -1,3 +0,0 @@
-#include "config_collada.cxx"
-#include "load_collada_file.cxx"
-#include "loaderFileTypeDae.cxx"

+ 0 - 28
panda/src/collada/pre_collada_include.h

@@ -1,28 +0,0 @@
-/**
- * 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."
- *
- * @file pre_collada_include.h
- * @author rdb
- * @date 2011-05-23
- */
-
-// This header file should be included before including any of the COLLADA DOM
-// headers.  It should only be included in a .cxx file (not in a header file)
-// and no Panda3D headers should be included after the pre_collada_include.h
-// include.
-
-#ifdef PRE_COLLADA_INCLUDE_H
-#error Don't include any Panda headers after including pre_collada_include.h!
-#endif
-#define PRE_COLLADA_INCLUDE_H
-
-// Undef some macros that conflict with COLLADA.
-#undef INLINE
-#undef tolower
-
-#include <dae.h>

+ 1 - 1
panda/src/device/clientBase.h

@@ -27,7 +27,7 @@
 #include "coordinateSystem.h"
 
 #ifdef OLD_HAVE_IPC
-#include "ipc_thread.h"
+#include <ipc_thread.h>
 #endif
 
 #include "pmap.h"

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

@@ -0,0 +1,4 @@
+#include "graphicsStateGuardian_ext.cxx"
+#include "graphicsWindow_ext.cxx"
+#include "pythonGraphicsWindowProc.cxx"
+#include "windowProperties_ext.cxx"

+ 2 - 0
panda/src/display/windowProperties.cxx

@@ -135,6 +135,8 @@ clear_default() {
 /**
  * Returns a WindowProperties structure with only the size specified.  The
  * size is the only property that matters to buffers.
+ *
+ * @deprecated in the Python API, use WindowProperties(size=(x, y)) instead.
  */
 WindowProperties WindowProperties::
 size(const LVecBase2i &size) {

+ 7 - 2
panda/src/display/windowProperties.h

@@ -27,6 +27,10 @@
  * properties for a window after it has been opened.
  */
 class EXPCL_PANDA_DISPLAY WindowProperties {
+public:
+  WindowProperties();
+  INLINE WindowProperties(const WindowProperties &copy);
+
 PUBLISHED:
   enum ZOrder {
     Z_bottom,
@@ -40,8 +44,9 @@ PUBLISHED:
     M_confined,
   };
 
-  WindowProperties();
-  INLINE WindowProperties(const WindowProperties &copy);
+  EXTENSION(WindowProperties(PyObject *self, PyObject *args, PyObject *kwds));
+
+PUBLISHED:
   void operator = (const WindowProperties &copy);
   INLINE ~WindowProperties();
 

+ 82 - 0
panda/src/display/windowProperties_ext.cxx

@@ -0,0 +1,82 @@
+/**
+ * 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."
+ *
+ * @file windowProperties_ext.cxx
+ * @author rdb
+ * @date 2018-11-12
+ */
+
+#include "windowProperties_ext.h"
+
+#ifdef HAVE_PYTHON
+
+extern struct Dtool_PyTypedObject Dtool_WindowProperties;
+
+/**
+ * Creates a new WindowProperties initialized with the given properties.
+ */
+void Extension<WindowProperties>::
+__init__(PyObject *self, PyObject *args, PyObject *kwds) {
+  nassertv_always(_this != nullptr);
+
+  // We need to initialize the self object before we can use it.
+  DtoolInstance_INIT_PTR(self, _this);
+
+  // Support copy constructor by extracting the one positional argument.
+  Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+  if (nargs != 0) {
+    if (nargs != 1) {
+      PyErr_Format(PyExc_TypeError,
+                   "WindowProperties() takes at most 1 positional argument (%d given)",
+                   (int)nargs);
+      return;
+    }
+
+    PyObject *arg = PyTuple_GET_ITEM(args, 0);
+    const WindowProperties *copy_from;
+    if (DtoolInstance_GetPointer(arg, copy_from, Dtool_WindowProperties)) {
+      *_this = *copy_from;
+    } else {
+      Dtool_Raise_ArgTypeError(arg, 0, "WindowProperties", "WindowProperties");
+      return;
+    }
+  }
+
+  // Now iterate over the keyword arguments, which define the default values
+  // for the different properties.
+  if (kwds != nullptr) {
+    PyTypeObject *type = Py_TYPE(self);
+    PyObject *key, *value;
+    Py_ssize_t pos = 0;
+
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+      // Look for a writable property on the type by this name.
+      PyObject *descr = _PyType_Lookup(type, key);
+
+      if (descr != nullptr && Py_TYPE(descr)->tp_descr_set != nullptr) {
+        if (Py_TYPE(descr)->tp_descr_set(descr, self, value) < 0) {
+          return;
+        }
+      } else {
+        PyObject *key_repr = PyObject_Repr(key);
+        PyErr_Format(PyExc_TypeError,
+                     "%.100s is an invalid keyword argument for WindowProperties()",
+#if PY_MAJOR_VERSION >= 3
+                     PyUnicode_AsUTF8(key_repr)
+#else
+                     PyString_AsString(key_repr)
+#endif
+                    );
+        Py_DECREF(key_repr);
+        return;
+      }
+    }
+  }
+}
+
+#endif  // HAVE_PYTHON

+ 37 - 0
panda/src/display/windowProperties_ext.h

@@ -0,0 +1,37 @@
+/**
+ * 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."
+ *
+ * @file windowProperties_ext.h
+ * @author rdb
+ * @date 2018-11-12
+ */
+
+#ifndef WINDOWPROPERTIES_EXT_H
+#define WINDOWPROPERTIES_EXT_H
+
+#include "dtoolbase.h"
+
+#ifdef HAVE_PYTHON
+
+#include "extension.h"
+#include "windowProperties.h"
+#include "py_panda.h"
+
+/**
+ * This class defines the extension methods for WindowProperties, which are
+ * called instead of any C++ methods with the same prototype.
+ */
+template<>
+class Extension<WindowProperties> : public ExtensionBase<WindowProperties> {
+public:
+  void __init__(PyObject *self, PyObject *args, PyObject *kwds);
+};
+
+#endif  // HAVE_PYTHON
+
+#endif  // WINDOWPROPERTIES_EXT_H

+ 1 - 1
panda/src/downloader/bioPtr.cxx

@@ -19,7 +19,7 @@
 #include "config_downloader.h"
 
 #include "openSSLWrapper.h"  // must be included before any other openssl.
-#include "openssl/ssl.h"
+#include <openssl/ssl.h>
 
 #ifdef _WIN32
 #include <winsock2.h>

+ 2 - 1
panda/src/downloader/httpCookie.cxx

@@ -15,9 +15,10 @@
 
 #ifdef HAVE_OPENSSL
 
-#include "ctype.h"
 #include "httpChannel.h"
 
+#include <ctype.h>
+
 using std::string;
 
 /**

+ 2 - 2
panda/src/downloader/httpDigestAuthorization.cxx

@@ -17,8 +17,8 @@
 
 #include "httpChannel.h"
 #include "openSSLWrapper.h"  // must be included before any other openssl.
-#include "openssl/ssl.h"
-#include "openssl/md5.h"
+#include <openssl/ssl.h>
+#include <openssl/md5.h>
 #include <time.h>
 
 using std::ostream;

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