Parcourir la source

Merge branch 'master' into webgl-port

rdb il y a 10 ans
Parent
commit
6357c3dea6
100 fichiers modifiés avec 1977 ajouts et 1216 suppressions
  1. 1 1
      .travis.yml
  2. 6 1
      README.md
  3. 4 13
      contrib/src/contribbase/contribsymbols.h
  4. 4 13
      direct/src/directbase/directsymbols.h
  5. 1 1
      direct/src/http/baseincomingset.i
  6. 15 8
      direct/src/p3d/DeploymentTools.py
  7. 0 2
      direct/src/showbase/PythonUtil.py
  8. 12 4
      direct/src/showbase/ShowBase.py
  9. 11 4
      direct/src/task/Task.py
  10. 31 0
      doc/ReleaseNotes
  11. 4 1
      doc/man/interrogate_module.1
  12. 1 1
      dtool/PandaVersion.pp
  13. 2 2
      dtool/src/cppparser/Sources.pp
  14. 11 0
      dtool/src/cppparser/cppArrayType.cxx
  15. 1 0
      dtool/src/cppparser/cppArrayType.h
  16. 466 457
      dtool/src/cppparser/cppBison.cxx.prebuilt
  17. 118 114
      dtool/src/cppparser/cppBison.h.prebuilt
  18. 11 0
      dtool/src/cppparser/cppConstType.cxx
  19. 1 0
      dtool/src/cppparser/cppConstType.h
  20. 11 0
      dtool/src/cppparser/cppExtensionType.cxx
  21. 1 0
      dtool/src/cppparser/cppExtensionType.h
  22. 5 2
      dtool/src/cppparser/cppFile.cxx
  23. 1 0
      dtool/src/cppparser/cppFile.h
  24. 11 0
      dtool/src/cppparser/cppFunctionType.cxx
  25. 11 8
      dtool/src/cppparser/cppFunctionType.h
  26. 26 2
      dtool/src/cppparser/cppInstance.cxx
  27. 10 1
      dtool/src/cppparser/cppInstanceIdentifier.cxx
  28. 11 0
      dtool/src/cppparser/cppPointerType.cxx
  29. 1 0
      dtool/src/cppparser/cppPointerType.h
  30. 27 2
      dtool/src/cppparser/cppPreprocessor.cxx
  31. 2 0
      dtool/src/cppparser/cppPreprocessor.h
  32. 11 0
      dtool/src/cppparser/cppReferenceType.cxx
  33. 1 3
      dtool/src/cppparser/cppReferenceType.h
  34. 11 0
      dtool/src/cppparser/cppSimpleType.cxx
  35. 1 0
      dtool/src/cppparser/cppSimpleType.h
  36. 91 0
      dtool/src/cppparser/cppStructType.cxx
  37. 1 0
      dtool/src/cppparser/cppStructType.h
  38. 11 0
      dtool/src/cppparser/cppType.cxx
  39. 1 0
      dtool/src/cppparser/cppType.h
  40. 11 0
      dtool/src/cppparser/cppTypedefType.cxx
  41. 1 0
      dtool/src/cppparser/cppTypedefType.h
  42. 6 2
      dtool/src/dtoolbase/Sources.pp
  43. 17 1
      dtool/src/dtoolbase/dtoolbase.h
  44. 1 1
      dtool/src/dtoolbase/dtoolbase_cc.h
  45. 12 27
      dtool/src/dtoolbase/dtoolsymbols.h
  46. 1 1
      dtool/src/dtoolbase/epvector.h
  47. 2 0
      dtool/src/dtoolbase/pdtoa.cxx
  48. 0 22
      dtool/src/dtoolbase/typeHandle.I
  49. 4 2
      dtool/src/dtoolbase/typeHandle.h
  50. 4 0
      dtool/src/dtoolutil/executionEnvironment.cxx
  51. 5 12
      dtool/src/interrogate/functionRemap.cxx
  52. 355 145
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  53. 1 1
      dtool/src/interrogate/interfaceMakerPythonNative.h
  54. 2 2
      dtool/src/interrogate/interrogate.cxx
  55. 31 23
      dtool/src/interrogate/interrogateBuilder.cxx
  56. 53 2
      dtool/src/interrogate/interrogate_module.cxx
  57. 56 1
      dtool/src/interrogate/typeManager.cxx
  58. 1 1
      dtool/src/interrogate/typeManager.h
  59. 12 9
      dtool/src/interrogatedb/dtool_super_base.cxx
  60. 0 20
      dtool/src/interrogatedb/interrogateType.cxx
  61. 0 10
      dtool/src/interrogatedb/interrogateType.h
  62. 122 54
      dtool/src/interrogatedb/py_panda.cxx
  63. 30 29
      dtool/src/interrogatedb/py_panda.h
  64. 3 0
      dtool/src/parser-inc/iostream
  65. 0 2
      dtool/src/parser-inc/stdtypedefs.h
  66. 48 43
      makepanda/makepanda.py
  67. 1 0
      makepanda/makepandacore.py
  68. 1 1
      panda/src/bullet/bulletRigidBodyNode.h
  69. 0 2
      panda/src/chan/animChannelMatrixFixed.h
  70. 2 2
      panda/src/dxgsg9/dxGeomMunger9.cxx
  71. 5 32
      panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx
  72. 0 3
      panda/src/dxgsg9/dxGraphicsStateGuardian9.h
  73. 1 1
      panda/src/egg/eggGroupNode.h
  74. 1 1
      panda/src/egg2pg/eggLoader.cxx
  75. 66 4
      panda/src/egg2pg/eggSaver.cxx
  76. 4 0
      panda/src/express/Sources.pp
  77. 3 3
      panda/src/express/memoryUsagePointers_ext.cxx
  78. 13 0
      panda/src/express/namable.I
  79. 5 1
      panda/src/express/namable.h
  80. 4 0
      panda/src/express/pta_uchar.h
  81. 5 71
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  82. 0 2
      panda/src/glstuff/glGraphicsStateGuardian_src.h
  83. 3 1
      panda/src/glstuff/glShaderContext_src.cxx
  84. 9 2
      panda/src/gobj/Sources.pp
  85. 1 1
      panda/src/gobj/geom.h
  86. 3 0
      panda/src/gobj/geomEnums.cxx
  87. 5 1
      panda/src/gobj/geomEnums.h
  88. 2 2
      panda/src/gobj/geomVertexArrayData.h
  89. 5 2
      panda/src/gobj/geomVertexArrayFormat.cxx
  90. 6 0
      panda/src/gobj/geomVertexColumn.cxx
  91. 64 7
      panda/src/gobj/geomVertexData.cxx
  92. 7 5
      panda/src/gobj/geomVertexData.h
  93. 7 6
      panda/src/gobj/geomVertexFormat.cxx
  94. 11 5
      panda/src/gobj/perspectiveLens.cxx
  95. 12 6
      panda/src/gobj/texture.cxx
  96. 1 1
      panda/src/gobj/texture.h
  97. 1 1
      panda/src/gobj/textureStage.h
  98. 3 0
      panda/src/grutil/geoMipTerrain.I
  99. 1 1
      panda/src/grutil/geoMipTerrain.cxx
  100. 2 2
      panda/src/grutil/pfmVizzer.cxx

+ 1 - 1
.travis.yml

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

+ 6 - 1
README.md

@@ -38,12 +38,17 @@ After acquiring these dependencies, you may simply build Panda3D from the
 command prompt using the following command:
 
 ```bash
-makepanda\makepanda.bat --everything --installer
+makepanda\makepanda.bat --everything --installer --no-eigen
 ```
 
 When the build succeeds, it will produce an .exe file that you can use to
 install Panda3D on your system.
 
+Note: you may choose to remove --no-eigen and build with Eigen support in
+order to improve runtime performance.  However, this will cause the build to
+take hours to complete, as Eigen is a heavily template-based library, and the
+the MSVC compiler does not perform well under these circumstances.
+
 Linux
 -----
 

+ 4 - 13
contrib/src/contribbase/contribsymbols.h

@@ -22,21 +22,12 @@
    C++-style comments, since this file is occasionally included by a C
    file. */
 
-#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
-
 #ifdef BUILDING_PANDAAI
-  #define EXPCL_PANDAAI __declspec(dllexport)
-  #define EXPTP_PANDAAI
+  #define EXPCL_PANDAAI EXPORT_CLASS
+  #define EXPTP_PANDAAI EXPORT_TEMPL
 #else
-  #define EXPCL_PANDAAI __declspec(dllimport)
-  #define EXPTP_PANDAAI extern
+  #define EXPCL_PANDAAI IMPORT_CLASS
+  #define EXPTP_PANDAAI IMPORT_TEMPL
 #endif
 
-#else   /* !WIN32_VC */
-
-#define EXPCL_PANDAAI
-#define EXPTP_PANDAAI
-
-#endif  /* WIN32_VC */
-
 #endif

+ 4 - 13
direct/src/directbase/directsymbols.h

@@ -17,21 +17,12 @@
 
 /* See dtoolsymbols.h for a rant on the purpose of this file.  */
 
-#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
-
 #ifdef BUILDING_DIRECT
-  #define EXPCL_DIRECT __declspec(dllexport)
-  #define EXPTP_DIRECT
+  #define EXPCL_DIRECT EXPORT_CLASS
+  #define EXPTP_DIRECT EXPORT_TEMPL
 #else
-  #define EXPCL_DIRECT __declspec(dllimport)
-  #define EXPTP_DIRECT extern
+  #define EXPCL_DIRECT IMPORT_CLASS
+  #define EXPTP_DIRECT IMPORT_TEMPL
 #endif
 
-#else   /* !WIN32_VC */
-
-#define EXPCL_DIRECT
-#define EXPTP_DIRECT
-
-#endif  /* WIN32_VC */
-
 #endif

+ 1 - 1
direct/src/http/baseincomingset.i

@@ -70,7 +70,7 @@ inline int BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READE
 template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS>
 inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddAConection(_INCLASS1 * newt)
 {
-    push_back(newt);
+    this->push_back(newt);
 }
 ////////////////////////////////////////////////////////////////////
 // Function name    : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet

+ 15 - 8
direct/src/p3d/DeploymentTools.py

@@ -73,7 +73,7 @@ class Standalone:
 
         self.tempDir = Filename.temporary("", self.basename, "") + "/"
         self.tempDir.makeDir()
-        self.host = HostInfo(PandaSystem.getPackageHostUrl(), appRunner = appRunner, hostDir = self.tempDir, asMirror = False, perPlatform = True)
+        self.host = HostInfo(PandaSystem.getPackageHostUrl(), appRunner = appRunner, hostDir = self.tempDir, asMirror = False)
 
         self.http = HTTPClient.getGlobalPtr()
         if not self.host.hasContentsFile:
@@ -233,7 +233,7 @@ class PackageTree:
         if hostUrl in self.hosts:
             return self.hosts[hostUrl]
 
-        host = HostInfo(hostUrl, appRunner = appRunner, hostDir = self.hostDir, asMirror = False, perPlatform = False)
+        host = HostInfo(hostUrl, appRunner = appRunner, hostDir = self.hostDir, asMirror = False)
         if not host.hasContentsFile:
             if not host.readContentsFile():
                 if not host.downloadContentsFile(self.http):
@@ -587,15 +587,22 @@ class Installer:
         for package in pkgTree.packages.values():
             xpackage = TiXmlElement('package')
             xpackage.SetAttribute('name', package.packageName)
+
+            filename = package.packageName + "/"
+
+            if package.packageVersion:
+                xpackage.SetAttribute('version', package.packageVersion)
+                filename += package.packageVersion + "/"
+
             if package.platform:
                 xpackage.SetAttribute('platform', package.platform)
+                filename += package.platform + "/"
                 assert package.platform == platform
-            xpackage.SetAttribute('per_platform', '0')
-            if package.packageVersion:
-                xpackage.SetAttribute('version', version)
-                xpackage.SetAttribute('filename', package.packageName + "/" + package.packageVersion + "/" + package.descFileBasename)
-            else:
-                xpackage.SetAttribute('filename', package.packageName + "/" + package.descFileBasename)
+
+            xpackage.SetAttribute('per_platform', '1')
+
+            filename += package.descFileBasename
+            xpackage.SetAttribute('filename', filename)
             xcontents.InsertEndChild(xpackage)
 
         doc.InsertEndChild(xcontents)

+ 0 - 2
direct/src/showbase/PythonUtil.py

@@ -49,8 +49,6 @@ import traceback
 import __builtin__
 from StringIO import StringIO
 import marshal
-import unicodedata
-import bisect
 
 __report_indent = 3
 

+ 12 - 4
direct/src/showbase/ShowBase.py

@@ -2466,7 +2466,8 @@ class ShowBase(DirectObject.DirectObject):
     def saveCubeMap(self, namePrefix = 'cube_map_#.png',
                     defaultFilename = 0, source = None,
                     camera = None, size = 128,
-                    cameraMask = PandaNode.getAllCameraMask()):
+                    cameraMask = PandaNode.getAllCameraMask(),
+                    sourceLens = None):
 
         """
         Similar to screenshot(), this sets up a temporary cube map
@@ -2494,6 +2495,9 @@ class ShowBase(DirectObject.DirectObject):
             if camera == None:
                 camera = base.camera
 
+        if sourceLens == None:
+            sourceLens = base.camLens
+
         if hasattr(source, "getWindow"):
             source = source.getWindow()
 
@@ -2504,7 +2508,8 @@ class ShowBase(DirectObject.DirectObject):
 
         # Set the near and far planes from the default lens.
         lens = rig.find('**/+Camera').node().getLens()
-        lens.setNearFar(base.camLens.getNear(), base.camLens.getFar())
+
+        lens.setNearFar(sourceLens.getNear(), sourceLens.getFar())
 
         # Now render a frame to fill up the texture.
         rig.reparentTo(camera)
@@ -2525,7 +2530,7 @@ class ShowBase(DirectObject.DirectObject):
                       defaultFilename = 0, source = None,
                       camera = None, size = 256,
                       cameraMask = PandaNode.getAllCameraMask(),
-                      numVertices = 1000):
+                      numVertices = 1000, sourceLens = None):
         """
         This works much like saveCubeMap(), and uses the graphics
         API's hardware cube-mapping ability to get a 360-degree view
@@ -2550,6 +2555,9 @@ class ShowBase(DirectObject.DirectObject):
             if camera == None:
                 camera = base.camera
 
+        if sourceLens == None:
+            sourceLens = base.camLens
+
         if hasattr(source, "getWindow"):
             source = source.getWindow()
 
@@ -2568,7 +2576,7 @@ class ShowBase(DirectObject.DirectObject):
 
         # Set the near and far planes from the default lens.
         lens = rig.find('**/+Camera').node().getLens()
-        lens.setNearFar(base.camLens.getNear(), base.camLens.getFar())
+        lens.setNearFar(sourceLens.getNear(), sourceLens.getFar())
 
         # Set up the scene to convert the cube map.  It's just a
         # simple scene, with only the FisheyeMaker object in it.

+ 11 - 4
direct/src/task/Task.py

@@ -10,12 +10,16 @@ from direct.directnotify.DirectNotifyGlobal import *
 from direct.showbase import ExceptionVarDump
 from direct.showbase.PythonUtil import *
 from direct.showbase.MessengerGlobal import messenger
-import signal
 import types
 import time
 import random
 import string
 
+try:
+    import signal
+except ImportError:
+    signal = None
+
 from panda3d.core import *
 
 def print_exc_plus():
@@ -149,7 +153,8 @@ class TaskManager:
     def invokeDefaultHandler(self, signalNumber, stackFrame):
         print '*** allowing mid-frame keyboard interrupt.'
         # Restore default interrupt handler
-        signal.signal(signal.SIGINT, signal.default_int_handler)
+        if signal:
+            signal.signal(signal.SIGINT, signal.default_int_handler)
         # and invoke it
         raise KeyboardInterrupt
 
@@ -454,7 +459,8 @@ class TaskManager:
         # after task list processing is complete.
         self.fKeyboardInterrupt = 0
         self.interruptCount = 0
-        signal.signal(signal.SIGINT, self.keyboardInterruptHandler)
+        if signal:
+            signal.signal(signal.SIGINT, self.keyboardInterruptHandler)
 
         startFrameTime = self.globalClock.getRealTime()
 
@@ -465,7 +471,8 @@ class TaskManager:
         self.doYield(startFrameTime, nextTaskTime)
 
         # Restore default interrupt handler
-        signal.signal(signal.SIGINT, signal.default_int_handler)
+        if signal:
+            signal.signal(signal.SIGINT, signal.default_int_handler)
         if self.fKeyboardInterrupt:
             raise KeyboardInterrupt
 

+ 31 - 0
doc/ReleaseNotes

@@ -1,3 +1,34 @@
+------------------------  RELEASE 1.9.1  ------------------------
+
+This minor release fixes some important regressions and bugs found
+in 1.9.0, but also introduces a few minor features.
+
+It also reintroduces the deployment pipeline that was absent from
+the previous release.
+
+* Textures were not being scaled to power-of-2 in some cases
+* Fix various issues with shader inputs
+* Bullet step function accidentally defaulted to step size of 0
+* Use model-path for finding libRocket assets
+* Fix inconsistent behavior with non-power-of-2 textures in rocket
+* Fix regression with memoryviews
+* Fix symbol error when loading libp3ffmpeg on Mac OS X
+* Fix issues running maya2egg on Mac OS X
+* PStats now tracks memory residency of graphics buffers
+* Support wireframe and point rendering modes in OpenGL ES
+* Add missing keys to libRocket keymap
+* Fix incorrect parsing of numbers with exponents in Config.prc
+* Various performance optimizations
+* Fix for reading URLs mounted via the virtual file system
+* Improve GLSL error reporting
+* Fix issue with model disappearing in rare cases with GLSL
+* Fix shader generator memory leaks and runtime performance
+* Add M_confined mouse mode that keeps cursor in window
+* Expose _NET_WM_PID to window managers in X11
+* bam2egg supports collision sphere and plane solids
+* Add sample program demonstrating mouse modes
+* Add -L (lighting) and -P (graphics pipe) pview options
+
 ------------------------  RELEASE 1.9.0  ------------------------
 
 This is a major release with many exciting new features!

+ 4 - 1
doc/man/interrogate_module.1

@@ -1,4 +1,4 @@
-.TH INTERROGATE_MODULE 1 "26 December 2014" "" Panda3D
+.TH INTERROGATE_MODULE 1 "02 June 2015" "" Panda3D
 .SH NAME
 interrogate_module \- generate module-level code for interrogate
 .SH SYNOPSIS
@@ -64,6 +64,9 @@ may be specified. If all are omitted, the default is \fB\-c\fP.
 Generate code within each wrapper function to adjust the global
 variable "in_interpreter" to indicated whether code is running
 within the Panda C++ environment or within the high-level language.
+.TP
+.BI "\-import " module_name
+Used to import an external dependency module.
 .SH "SEE ALSO"
 .BR interrogate (1),
 .BR test_interrogate (1)

+ 1 - 1
dtool/PandaVersion.pp

@@ -3,7 +3,7 @@
 // ppremake scripts for Panda.
 
 // Use spaces to separate the major, minor, and sequence numbers here.
-#define PANDA_VERSION 1 9 0
+#define PANDA_VERSION 1 10 0
 
 // This variable will be defined to false in the CVS repository, but
 // scripts that generate source tarballs and/or binary releases for

+ 2 - 2
dtool/src/cppparser/Sources.pp

@@ -22,7 +22,7 @@
      cppSimpleType.h cppStructType.h cppTBDType.h  \
      cppTemplateParameterList.h cppTemplateScope.h cppToken.h  \
      cppType.h cppTypeDeclaration.h cppTypeParser.h  \
-     cppTypeProxy.h cppTypedef.h cppUsing.h cppVisibility.h 
+     cppTypeProxy.h cppTypedefType.h cppUsing.h cppVisibility.h
 
   #define INCLUDED_SOURCES  \
      cppArrayType.cxx cppClassTemplateParameter.cxx  \
@@ -38,7 +38,7 @@
      cppStructType.cxx cppTBDType.cxx  \
      cppTemplateParameterList.cxx cppTemplateScope.cxx  \
      cppToken.cxx cppType.cxx cppTypeDeclaration.cxx  \
-     cppTypeParser.cxx cppTypeProxy.cxx cppTypedef.cxx  \
+     cppTypeParser.cxx cppTypeProxy.cxx cppTypedefType.cxx  \
      cppUsing.cxx cppVisibility.cxx
 
 #end static_lib_target

+ 11 - 0
dtool/src/cppparser/cppArrayType.cxx

@@ -76,6 +76,17 @@ is_tbd() const {
   return _element_type->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPArrayType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPArrayType::
+is_trivial() const {
+  return _element_type->is_trivial();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPArrayType::is_equivalent
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppArrayType.h

@@ -40,6 +40,7 @@ public:
   virtual CPPType *resolve_type(CPPScope *current_scope,
                                 CPPScope *global_scope);
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

Fichier diff supprimé car celui-ci est trop grand
+ 466 - 457
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 118 - 114
dtool/src/cppparser/cppBison.h.prebuilt

@@ -91,63 +91,65 @@ extern int cppyydebug;
      KW_BOOL = 300,
      KW_CATCH = 301,
      KW_CHAR = 302,
-     KW_WCHAR_T = 303,
-     KW_CLASS = 304,
-     KW_CONST = 305,
-     KW_DELETE = 306,
-     KW_DOUBLE = 307,
-     KW_DYNAMIC_CAST = 308,
-     KW_ELSE = 309,
-     KW_END_PUBLISH = 310,
-     KW_ENUM = 311,
-     KW_EXTENSION = 312,
-     KW_EXTERN = 313,
-     KW_EXPLICIT = 314,
-     KW_PUBLISHED = 315,
-     KW_FALSE = 316,
-     KW_FLOAT = 317,
-     KW_FRIEND = 318,
-     KW_FOR = 319,
-     KW_GOTO = 320,
-     KW_IF = 321,
-     KW_INLINE = 322,
-     KW_INT = 323,
-     KW_LONG = 324,
-     KW_LONGLONG = 325,
-     KW_MAKE_PROPERTY = 326,
-     KW_MAKE_SEQ = 327,
-     KW_MUTABLE = 328,
-     KW_NAMESPACE = 329,
-     KW_NEW = 330,
-     KW_NOEXCEPT = 331,
-     KW_OPERATOR = 332,
-     KW_PRIVATE = 333,
-     KW_PROTECTED = 334,
-     KW_PUBLIC = 335,
-     KW_REGISTER = 336,
-     KW_RETURN = 337,
-     KW_SHORT = 338,
-     KW_SIGNED = 339,
-     KW_SIZEOF = 340,
-     KW_STATIC = 341,
-     KW_STATIC_CAST = 342,
-     KW_STRUCT = 343,
-     KW_TEMPLATE = 344,
-     KW_THROW = 345,
-     KW_TRUE = 346,
-     KW_TRY = 347,
-     KW_TYPEDEF = 348,
-     KW_TYPENAME = 349,
-     KW_UNION = 350,
-     KW_UNSIGNED = 351,
-     KW_USING = 352,
-     KW_VIRTUAL = 353,
-     KW_VOID = 354,
-     KW_VOLATILE = 355,
-     KW_WHILE = 356,
-     START_CPP = 357,
-     START_CONST_EXPR = 358,
-     START_TYPE = 359
+     KW_CHAR16_T = 303,
+     KW_CHAR32_T = 304,
+     KW_CLASS = 305,
+     KW_CONST = 306,
+     KW_DELETE = 307,
+     KW_DOUBLE = 308,
+     KW_DYNAMIC_CAST = 309,
+     KW_ELSE = 310,
+     KW_END_PUBLISH = 311,
+     KW_ENUM = 312,
+     KW_EXTENSION = 313,
+     KW_EXTERN = 314,
+     KW_EXPLICIT = 315,
+     KW_PUBLISHED = 316,
+     KW_FALSE = 317,
+     KW_FLOAT = 318,
+     KW_FRIEND = 319,
+     KW_FOR = 320,
+     KW_GOTO = 321,
+     KW_IF = 322,
+     KW_INLINE = 323,
+     KW_INT = 324,
+     KW_LONG = 325,
+     KW_LONGLONG = 326,
+     KW_MAKE_PROPERTY = 327,
+     KW_MAKE_SEQ = 328,
+     KW_MUTABLE = 329,
+     KW_NAMESPACE = 330,
+     KW_NEW = 331,
+     KW_NOEXCEPT = 332,
+     KW_OPERATOR = 333,
+     KW_PRIVATE = 334,
+     KW_PROTECTED = 335,
+     KW_PUBLIC = 336,
+     KW_REGISTER = 337,
+     KW_RETURN = 338,
+     KW_SHORT = 339,
+     KW_SIGNED = 340,
+     KW_SIZEOF = 341,
+     KW_STATIC = 342,
+     KW_STATIC_CAST = 343,
+     KW_STRUCT = 344,
+     KW_TEMPLATE = 345,
+     KW_THROW = 346,
+     KW_TRUE = 347,
+     KW_TRY = 348,
+     KW_TYPEDEF = 349,
+     KW_TYPENAME = 350,
+     KW_UNION = 351,
+     KW_UNSIGNED = 352,
+     KW_USING = 353,
+     KW_VIRTUAL = 354,
+     KW_VOID = 355,
+     KW_VOLATILE = 356,
+     KW_WCHAR_T = 357,
+     KW_WHILE = 358,
+     START_CPP = 359,
+     START_CONST_EXPR = 360,
+     START_TYPE = 361
    };
 #endif
 /* Tokens.  */
@@ -196,63 +198,65 @@ extern int cppyydebug;
 #define KW_BOOL 300
 #define KW_CATCH 301
 #define KW_CHAR 302
-#define KW_WCHAR_T 303
-#define KW_CLASS 304
-#define KW_CONST 305
-#define KW_DELETE 306
-#define KW_DOUBLE 307
-#define KW_DYNAMIC_CAST 308
-#define KW_ELSE 309
-#define KW_END_PUBLISH 310
-#define KW_ENUM 311
-#define KW_EXTENSION 312
-#define KW_EXTERN 313
-#define KW_EXPLICIT 314
-#define KW_PUBLISHED 315
-#define KW_FALSE 316
-#define KW_FLOAT 317
-#define KW_FRIEND 318
-#define KW_FOR 319
-#define KW_GOTO 320
-#define KW_IF 321
-#define KW_INLINE 322
-#define KW_INT 323
-#define KW_LONG 324
-#define KW_LONGLONG 325
-#define KW_MAKE_PROPERTY 326
-#define KW_MAKE_SEQ 327
-#define KW_MUTABLE 328
-#define KW_NAMESPACE 329
-#define KW_NEW 330
-#define KW_NOEXCEPT 331
-#define KW_OPERATOR 332
-#define KW_PRIVATE 333
-#define KW_PROTECTED 334
-#define KW_PUBLIC 335
-#define KW_REGISTER 336
-#define KW_RETURN 337
-#define KW_SHORT 338
-#define KW_SIGNED 339
-#define KW_SIZEOF 340
-#define KW_STATIC 341
-#define KW_STATIC_CAST 342
-#define KW_STRUCT 343
-#define KW_TEMPLATE 344
-#define KW_THROW 345
-#define KW_TRUE 346
-#define KW_TRY 347
-#define KW_TYPEDEF 348
-#define KW_TYPENAME 349
-#define KW_UNION 350
-#define KW_UNSIGNED 351
-#define KW_USING 352
-#define KW_VIRTUAL 353
-#define KW_VOID 354
-#define KW_VOLATILE 355
-#define KW_WHILE 356
-#define START_CPP 357
-#define START_CONST_EXPR 358
-#define START_TYPE 359
+#define KW_CHAR16_T 303
+#define KW_CHAR32_T 304
+#define KW_CLASS 305
+#define KW_CONST 306
+#define KW_DELETE 307
+#define KW_DOUBLE 308
+#define KW_DYNAMIC_CAST 309
+#define KW_ELSE 310
+#define KW_END_PUBLISH 311
+#define KW_ENUM 312
+#define KW_EXTENSION 313
+#define KW_EXTERN 314
+#define KW_EXPLICIT 315
+#define KW_PUBLISHED 316
+#define KW_FALSE 317
+#define KW_FLOAT 318
+#define KW_FRIEND 319
+#define KW_FOR 320
+#define KW_GOTO 321
+#define KW_IF 322
+#define KW_INLINE 323
+#define KW_INT 324
+#define KW_LONG 325
+#define KW_LONGLONG 326
+#define KW_MAKE_PROPERTY 327
+#define KW_MAKE_SEQ 328
+#define KW_MUTABLE 329
+#define KW_NAMESPACE 330
+#define KW_NEW 331
+#define KW_NOEXCEPT 332
+#define KW_OPERATOR 333
+#define KW_PRIVATE 334
+#define KW_PROTECTED 335
+#define KW_PUBLIC 336
+#define KW_REGISTER 337
+#define KW_RETURN 338
+#define KW_SHORT 339
+#define KW_SIGNED 340
+#define KW_SIZEOF 341
+#define KW_STATIC 342
+#define KW_STATIC_CAST 343
+#define KW_STRUCT 344
+#define KW_TEMPLATE 345
+#define KW_THROW 346
+#define KW_TRUE 347
+#define KW_TRY 348
+#define KW_TYPEDEF 349
+#define KW_TYPENAME 350
+#define KW_UNION 351
+#define KW_UNSIGNED 352
+#define KW_USING 353
+#define KW_VIRTUAL 354
+#define KW_VOID 355
+#define KW_VOLATILE 356
+#define KW_WCHAR_T 357
+#define KW_WHILE 358
+#define START_CPP 359
+#define START_CONST_EXPR 360
+#define START_TYPE 361
 
 
 

+ 11 - 0
dtool/src/cppparser/cppConstType.cxx

@@ -101,6 +101,17 @@ is_tbd() const {
   return _wrapped_around->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPConstType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPConstType::
+is_trivial() const {
+  return _wrapped_around->is_trivial();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPConstType::is_equivalent
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppConstType.h

@@ -38,6 +38,7 @@ public:
                                 CPPScope *global_scope);
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 11 - 0
dtool/src/cppparser/cppExtensionType.cxx

@@ -102,6 +102,17 @@ is_tbd() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPExtensionType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPExtensionType::
+is_trivial() const {
+  return (_type == T_enum);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPExtensionType::substitute_decl
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppExtensionType.h

@@ -47,6 +47,7 @@ public:
 
   virtual bool is_incomplete() const;
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
 
   virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
                                           CPPScope *current_scope,

+ 5 - 2
dtool/src/cppparser/cppFile.cxx

@@ -26,7 +26,8 @@ CPPFile::
 CPPFile(const Filename &filename, const Filename &filename_as_referenced,
         Source source) :
   _filename(filename), _filename_as_referenced(filename_as_referenced),
-  _source(source)
+  _source(source),
+  _pragma_once(false)
 {
   _filename.set_text();
   _filename_as_referenced.set_text();
@@ -42,7 +43,8 @@ CPPFile::
 CPPFile(const CPPFile &copy) :
   _filename(copy._filename),
   _filename_as_referenced(copy._filename_as_referenced),
-  _source(copy._source)
+  _source(copy._source),
+  _pragma_once(copy._pragma_once)
 {
 }
 
@@ -56,6 +58,7 @@ operator = (const CPPFile &copy) {
   _filename = copy._filename;
   _filename_as_referenced = copy._filename_as_referenced;
   _source = copy._source;
+  _pragma_once = copy._pragma_once;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
dtool/src/cppparser/cppFile.h

@@ -59,6 +59,7 @@ public:
   Filename _filename;
   Filename _filename_as_referenced;
   Source _source;
+  mutable bool _pragma_once;
 };
 
 inline ostream &operator << (ostream &out, const CPPFile &file) {

+ 11 - 0
dtool/src/cppparser/cppFunctionType.cxx

@@ -159,6 +159,17 @@ is_tbd() const {
   return _parameters->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPFunctionType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPFunctionType::
+is_trivial() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPFunctionType::output
 //       Access: Public, Virtual

+ 11 - 8
dtool/src/cppparser/cppFunctionType.h

@@ -29,14 +29,16 @@ class CPPIdentifier;
 class CPPFunctionType : public CPPType {
 public:
   enum Flags {
-    F_const_method      = 0x01,
-    F_operator_typecast = 0x02,
-    F_constructor       = 0x04,
-    F_destructor        = 0x08,
-    F_method_pointer    = 0x10,
-    F_unary_op          = 0x20,
-    F_operator          = 0x40,
-    F_noexcept          = 0x80,
+    F_const_method      = 0x001,
+    F_operator_typecast = 0x002,
+    F_constructor       = 0x004,
+    F_destructor        = 0x008,
+    F_method_pointer    = 0x010,
+    F_unary_op          = 0x020,
+    F_operator          = 0x040,
+    F_noexcept          = 0x080,
+    F_copy_constructor  = 0x200,
+    F_move_constructor  = 0x400,
   };
 
   CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
@@ -57,6 +59,7 @@ public:
                                 CPPScope *global_scope);
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,
                       bool complete) const;

+ 26 - 2
dtool/src/cppparser/cppInstance.cxx

@@ -347,9 +347,33 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
         CPPType *void_type = CPPType::new_type
           (new CPPSimpleType(CPPSimpleType::T_void));
 
+        int flags = func->_flags | CPPFunctionType::F_constructor;
+
+        // Check if it might be a copy or move constructor.
+        CPPParameterList *params = func->_parameters;
+        if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
+          CPPType *param_type = params->_parameters[0]->_type;
+          CPPReferenceType *ref_type = param_type->as_reference_type();
+
+          if (ref_type != NULL) {
+            param_type = ref_type->_pointing_at;
+
+            if (param_type->get_subtype() == CPPDeclaration::ST_const) {
+              param_type = param_type->as_const_type()->_wrapped_around;
+            }
+
+            if (class_name == param_type->get_simple_name()) {
+              if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
+                flags |= CPPFunctionType::F_move_constructor;
+              } else {
+                flags |= CPPFunctionType::F_copy_constructor;
+              }
+            }
+          }
+        }
+
         _type = CPPType::new_type
-          (new CPPFunctionType(void_type, func->_parameters,
-                               func->_flags | CPPFunctionType::F_constructor));
+          (new CPPFunctionType(void_type, func->_parameters, flags));
 
       } else if (method_name == "~" + class_name) {
         CPPType *void_type = CPPType::new_type

+ 10 - 1
dtool/src/cppparser/cppInstanceIdentifier.cxx

@@ -166,7 +166,16 @@ add_scoped_pointer_modifier(CPPIdentifier *scoping) {
 ////////////////////////////////////////////////////////////////////
 void CPPInstanceIdentifier::
 add_array_modifier(CPPExpression *expr) {
-  _modifiers.push_back(Modifier::array_type(expr));
+  // Special case for operator new[] and delete[].  We're not really
+  // adding an array modifier to them, but appending [] to the
+  // identifier.  This is to work around a parser ambiguity.
+  if (_ident != NULL && (_ident->get_simple_name() == "operator delete" ||
+                         _ident->get_simple_name() == "operator new")) {
+
+    _ident->_names.back().append_name("[]");
+  } else {
+    _modifiers.push_back(Modifier::array_type(expr));
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 11 - 0
dtool/src/cppparser/cppPointerType.cxx

@@ -103,6 +103,17 @@ is_tbd() const {
   return _pointing_at->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPPointerType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPPointerType::
+is_trivial() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPPointerType::is_equivalent
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppPointerType.h

@@ -38,6 +38,7 @@ public:
                                 CPPScope *global_scope);
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 27 - 2
dtool/src/cppparser/cppPreprocessor.cxx

@@ -620,6 +620,7 @@ push_file(const CPPFile &file) {
     indent(cerr, _files.size() * 2)
       << "Reading " << file << "\n";
   }
+
   _files.push_back(InputFile());
   InputFile &infile = _files.back();
 
@@ -1158,7 +1159,7 @@ process_directive(int c) {
   } else if (command == "include") {
     handle_include_directive(args, first_line, first_col, first_file);
   } else if (command == "pragma") {
-    // Quietly ignore pragmas.
+    handle_pragma_directive(args, first_line, first_col, first_file);
   } else if (command == "ident") {
     // Quietly ignore idents.
   } else if (command == "error") {
@@ -1462,7 +1463,16 @@ handle_include_directive(const string &args, int first_line,
               first_line, first_col, first_file);
     } else {
       _last_c = '\0';
-      if (!push_file(CPPFile(filename, filename_as_referenced, source))) {
+
+      CPPFile file(filename, filename_as_referenced, source);
+
+      // Don't include it if we included it before and it had #pragma once.
+      ParsedFiles::const_iterator it = _parsed_files.find(file);
+      if (it->_pragma_once) {
+        return;
+      }
+
+      if (!push_file(file)) {
         warning("Unable to read " + filename.get_fullpath(),
                 first_line, first_col, first_file);
       }
@@ -1473,6 +1483,21 @@ handle_include_directive(const string &args, int first_line,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPPreprocessor::handle_pragma_directive
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
+void CPPPreprocessor::
+handle_pragma_directive(const string &args, int first_line,
+                        int first_col, const CPPFile &first_file) {
+  if (args == "once") {
+    ParsedFiles::iterator it = _parsed_files.find(first_file);
+    assert(it != _parsed_files.end());
+    it->_pragma_once = true;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPPreprocessor::handle_error_directive
 //       Access: Private

+ 2 - 0
dtool/src/cppparser/cppPreprocessor.h

@@ -133,6 +133,8 @@ private:
                            int first_col, const CPPFile &first_file);
   void handle_include_directive(const string &args, int first_line,
                                 int first_col, const CPPFile &first_file);
+  void handle_pragma_directive(const string &args, int first_line,
+                               int first_col, const CPPFile &first_file);
   void handle_error_directive(const string &args, int first_line,
                               int first_col, const CPPFile &first_file);
 

+ 11 - 0
dtool/src/cppparser/cppReferenceType.cxx

@@ -102,6 +102,17 @@ is_tbd() const {
   return _pointing_at->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPReferenceType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPReferenceType::
+is_trivial() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPReferenceType::is_equivalent
 //       Access: Public, Virtual

+ 1 - 3
dtool/src/cppparser/cppReferenceType.h

@@ -35,9 +35,6 @@ public:
   CPPType *_pointing_at;
   ValueCategory _value_category;
 
-  inline bool is_lvalue() const;
-  inline bool is_rvalue() const;
-
   virtual bool is_fully_specified() const;
   virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
                                           CPPScope *current_scope,
@@ -47,6 +44,7 @@ public:
                                 CPPScope *global_scope);
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_equivalent(const CPPType &other) const;
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

+ 11 - 0
dtool/src/cppparser/cppSimpleType.cxx

@@ -40,6 +40,17 @@ is_tbd() const {
   return (_type == T_unknown);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPSimpleType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPSimpleType::
+is_trivial() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPSimpleType::is_parameter_expr
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppSimpleType.h

@@ -66,6 +66,7 @@ public:
   int _flags;
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_parameter_expr() const;
 
   virtual string get_preferred_name() const;

+ 91 - 0
dtool/src/cppparser/cppStructType.cxx

@@ -131,6 +131,97 @@ is_abstract() const {
   return !funcs.empty();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPStructType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPStructType::
+is_trivial() const {
+  // Make sure all base classes are trivial.
+  Derivation::const_iterator di;
+  for (di = _derivation.begin(); di != _derivation.end(); ++di) {
+    CPPStructType *base = (*di)._base->as_struct_type();
+    if (base != NULL && !base->is_trivial()) {
+      return false;
+    }
+  }
+
+  assert(_scope != NULL);
+
+  // Make sure all members are trivial.
+  CPPScope::Variables::const_iterator vi;
+  for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
+    CPPInstance *instance = (*vi).second;
+    assert(instance != NULL);
+
+    if (instance->_storage_class & CPPInstance::SC_static) {
+      // Static members don't count.
+      continue;
+    }
+
+    if (instance->_initializer != NULL) {
+      // A member with an initializer means the default constructor would
+      // assign a value.  This means the type can't be trivial.
+      return false;
+    }
+
+    // Finally, check if the data member itself is non-trivial.
+    assert(instance->_type != NULL);
+    if (!instance->_type->is_trivial()) {
+      return false;
+    }
+  }
+
+  // Now look for functions that are virtual or con/destructors.
+  bool is_default_constructible = true;
+  CPPScope::Functions::const_iterator fi;
+  for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) {
+    CPPFunctionGroup *fgroup = (*fi).second;
+
+    CPPFunctionGroup::Instances::const_iterator ii;
+    for (ii = fgroup->_instances.begin(); ii != fgroup->_instances.end(); ++ii) {
+      CPPInstance *inst = (*ii);
+
+      if (inst->_storage_class & CPPInstance::SC_virtual) {
+        // Virtual functions are banned right off the bat.
+        return false;
+      }
+
+      assert(inst->_type != (CPPType *)NULL);
+      CPPFunctionType *ftype = inst->_type->as_function_type();
+      assert(ftype != (CPPFunctionType *)NULL);
+
+      if (ftype->_flags & (CPPFunctionType::F_destructor |
+                           CPPFunctionType::F_move_constructor |
+                           CPPFunctionType::F_copy_constructor)) {
+        // User-provided destructors and copy/move constructors are not trivial.
+        return false;
+      }
+
+      if ((ftype->_flags & CPPFunctionType::F_constructor) != 0) {
+        if (ftype->_parameters->_parameters.size() == 0 &&
+            !ftype->_parameters->_includes_ellipsis) {
+          // Same for the default constructor.
+          return false;
+        }
+        // The presence of a non-default constructor makes the class not
+        // default-constructible.
+        is_default_constructible = false;
+      }
+
+      if (fgroup->_name == "operator =") {
+        // Or assignment operators.
+        return false;
+      }
+    }
+  }
+
+  // Finally, the class must be default-constructible.
+  return is_default_constructible;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPStructType::check_virtual
 //       Access: Public

+ 1 - 0
dtool/src/cppparser/cppStructType.h

@@ -47,6 +47,7 @@ public:
   bool check_virtual();
   virtual bool is_fully_specified() const;
   virtual bool is_incomplete() const;
+  virtual bool is_trivial() const;
 
   CPPInstance *get_destructor() const;
 

+ 11 - 0
dtool/src/cppparser/cppType.cxx

@@ -68,6 +68,17 @@ is_tbd() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPType::
+is_trivial() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPType::is_parameter_expr
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppType.h

@@ -48,6 +48,7 @@ public:
                                 CPPScope *global_scope);
 
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
   virtual bool is_parameter_expr() const;
 
   bool has_typedef_name() const;

+ 11 - 0
dtool/src/cppparser/cppTypedefType.cxx

@@ -178,6 +178,17 @@ is_tbd() const {
   return _type->is_tbd();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPTypedefType::is_trivial
+//       Access: Public, Virtual
+//  Description: Returns true if the type is considered a Plain Old
+//               Data (POD) type.
+////////////////////////////////////////////////////////////////////
+bool CPPTypedefType::
+is_trivial() const {
+  return _type->is_trivial();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPTypedefType::is_fully_specified
 //       Access: Public, Virtual

+ 1 - 0
dtool/src/cppparser/cppTypedefType.h

@@ -42,6 +42,7 @@ public:
 
   virtual bool is_incomplete() const;
   virtual bool is_tbd() const;
+  virtual bool is_trivial() const;
 
   virtual bool is_fully_specified() const;
 

+ 6 - 2
dtool/src/dtoolbase/Sources.pp

@@ -10,6 +10,7 @@
     addHash.I addHash.h \
     atomicAdjust.h \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
+    atomicAdjustGccImpl.h atomicAdjustGccImpl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
@@ -30,7 +31,7 @@
     nearly_zero.h \
     neverFreeMemory.h neverFreeMemory.I \
     numeric_types.h \
-    pstrtod.h \
+    pdtoa.h pstrtod.h \
     register_type.I register_type.h \
     selectThreadImpl.h \
     stl_compares.I stl_compares.h \
@@ -47,6 +48,7 @@
  #define INCLUDED_SOURCES  \
     addHash.cxx \
     atomicAdjustDummyImpl.cxx \
+    atomicAdjustGccImpl.cxx \
     atomicAdjustI386Impl.cxx \
     atomicAdjustPosixImpl.cxx \
     atomicAdjustWin32Impl.cxx \
@@ -59,6 +61,7 @@
     mutexWin32Impl.cxx \
     mutexSpinlockImpl.cxx \
     neverFreeMemory.cxx \
+    pdtoa.cxx \
     pstrtod.cxx \
     register_type.cxx \
     typeHandle.cxx \
@@ -69,6 +72,7 @@
     addHash.I addHash.h \
     atomicAdjust.h \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
+    atomicAdjustGccImpl.h atomicAdjustGccImpl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
@@ -89,7 +93,7 @@
     nearly_zero.h \
     neverFreeMemory.h neverFreeMemory.I \
     numeric_types.h \
-    pstrtod.h \
+    pdtoa.h pstrtod.h \
     register_type.I register_type.h \
     selectThreadImpl.h \
     stl_compares.I stl_compares.h \

+ 17 - 1
dtool/src/dtoolbase/dtoolbase.h

@@ -427,9 +427,25 @@
 #define EXTEND
 #endif
 
+/* These symbols are used in dtoolsymbols.h and pandasymbols.h. */
+#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
+#define EXPORT_CLASS __declspec(dllexport)
+#define IMPORT_CLASS __declspec(dllimport)
+#else
+#define EXPORT_CLASS
+#define IMPORT_CLASS
+#endif
+/* "extern template" is now part of the C++11 standard. */
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
+#define EXPORT_TEMPL
+#define IMPORT_TEMPL extern
+#else
+#define EXPORT_TEMPL
+#define IMPORT_TEMPL
+#endif
+
 #ifdef __cplusplus
 #include "dtoolbase_cc.h"
 #endif
 
 #endif
-

+ 1 - 1
dtool/src/dtoolbase/dtoolbase_cc.h

@@ -174,7 +174,7 @@ typedef ios::seekdir ios_seekdir;
 #  define MOVE(x) x
 #endif
 
-#if defined(WIN32_VC) && !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
+#if !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
 // This macro must be used to export an instantiated template class
 // from a DLL.  If the template class name itself contains commas, it
 // may be necessary to first define a macro for the class name, to

+ 12 - 27
dtool/src/dtoolbase/dtoolsymbols.h

@@ -70,45 +70,30 @@
 
 #define EXPCL_EMPTY
 
-#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
-
 #ifdef BUILDING_DTOOL
-  #define EXPCL_DTOOL __declspec(dllexport)
-  #define EXPTP_DTOOL
+  #define EXPCL_DTOOL EXPORT_CLASS
+  #define EXPTP_DTOOL EXPORT_TEMPL
 #else
-  #define EXPCL_DTOOL __declspec(dllimport)
-  #define EXPTP_DTOOL extern
+  #define EXPCL_DTOOL IMPORT_CLASS
+  #define EXPTP_DTOOL IMPORT_TEMPL
 #endif
 
 #ifdef BUILDING_DTOOLCONFIG
-  #define EXPCL_DTOOLCONFIG __declspec(dllexport)
-  #define EXPTP_DTOOLCONFIG
+  #define EXPCL_DTOOLCONFIG EXPORT_CLASS
+  #define EXPTP_DTOOLCONFIG EXPORT_TEMPL
 #else
-  #define EXPCL_DTOOLCONFIG __declspec(dllimport)
-  #define EXPTP_DTOOLCONFIG extern
+  #define EXPCL_DTOOLCONFIG IMPORT_CLASS
+  #define EXPTP_DTOOLCONFIG IMPORT_TEMPL
 #endif
 
 #ifdef BUILDING_MISC
-  #define EXPCL_MISC __declspec(dllexport)
-  #define EXPTP_MISC
+  #define EXPCL_MISC EXPORT_CLASS
+  #define EXPTP_MISC EXPORT_TEMPL
 #else /* BUILDING_MISC */
-  #define EXPCL_MISC __declspec(dllimport)
-  #define EXPTP_MISC extern
+  #define EXPCL_MISC IMPORT_CLASS
+  #define EXPTP_MISC IMPORT_TEMPL
 #endif /* BUILDING_MISC */
 
-#else   /* !WIN32_VC */
-
-#define EXPCL_DTOOL
-#define EXPTP_DTOOL
-
-#define EXPCL_DTOOLCONFIG
-#define EXPTP_DTOOLCONFIG
-
-#define EXPCL_MISC
-#define EXPTP_MISC
-
-#endif  /* WIN32_VC */
-
 /* These two are always defined empty, because pystub is statically
    built.  But we leave the symbol around in case we change our minds
    to make pystub once again be a dynamic library. */

+ 1 - 1
dtool/src/dtoolbase/epvector.h

@@ -17,7 +17,7 @@
 
 #include "pvector.h"
 
-#if defined(HAVE_EIGEN) && defined(_WIN32) && !defined(CPPPARSER)
+#if defined(HAVE_EIGEN) && defined(_WIN32) && !defined(_WIN64) && !defined(CPPPARSER)
 
 #include <Eigen/StdVector>
 

+ 2 - 0
dtool/src/dtoolbase/pdtoa.cxx

@@ -30,6 +30,8 @@ THE SOFTWARE.
 
 #if defined(_MSC_VER)
 #include <intrin.h>
+#include <float.h>
+#define copysign _copysign
 #endif
 
 #define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))

+ 0 - 22
dtool/src/dtoolbase/typeHandle.I

@@ -13,28 +13,6 @@
 ////////////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: TypeHandle::Constructor
-//       Access: Published
-//  Description: The default constructor must do nothing, because we
-//               can't guarantee ordering of static initializers.  If
-//               the constructor tried to initialize its value, it
-//               might happen after the value had already been set
-//               previously by another static initializer!
-////////////////////////////////////////////////////////////////////
-INLINE TypeHandle::
-TypeHandle() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TypeHandle::Copy Constructor
-//       Access: Published
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE TypeHandle::
-TypeHandle(const TypeHandle &copy) : _index(copy._index) {
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TypeHandle::Equality Operator
 //       Access: Published

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

@@ -94,8 +94,10 @@ PUBLISHED:
               // enum value.
   };
 
-  INLINE TypeHandle();
-  INLINE TypeHandle(const TypeHandle &copy);
+  // The default constructor must do nothing, because we can't
+  // guarantee ordering of static initializers.  If the constructor
+  // tried to initialize its value, it  might happen after the value
+  // had already been set previously by another static initializer!
 
   EXTENSION(static TypeHandle make(PyTypeObject *classobj));
 

+ 4 - 0
dtool/src/dtoolutil/executionEnvironment.cxx

@@ -272,7 +272,9 @@ ns_get_environment_variable(const string &var) const {
       // marked BLOCKING, which releases the Python thread state, we
       // have to temporarily re-establish our thread state in the
       // Python interpreter.
+#ifdef WITH_THREAD
       PyGILState_STATE state = PyGILState_Ensure();
+#endif
 
       Filename main_dir;
       PyObject *obj = PySys_GetObject((char*) "argv");  // borrowed reference
@@ -303,7 +305,9 @@ ns_get_environment_variable(const string &var) const {
         }
       }
 
+#ifdef WITH_THREAD
       PyGILState_Release(state);
+#endif
 
       if (main_dir.empty()) {
         // We must be running in the Python interpreter directly, so return the CWD.

+ 5 - 12
dtool/src/interrogate/functionRemap.cxx

@@ -30,8 +30,6 @@
 #include "interrogateType.h"
 #include "pnotify.h"
 
-extern bool inside_python_native;
-
 ////////////////////////////////////////////////////////////////////
 //     Function: FunctionRemap::Constructor
 //       Access: Public
@@ -120,11 +118,7 @@ call_function(ostream &out, int indent_level, bool convert_result,
       InterfaceMaker::indent(out, indent_level)
         << "unref_delete(" << container << ");\n";
     } else {
-      if (inside_python_native) {
-        InterfaceMaker::indent(out, indent_level) << "Dtool_Py_Delete(self);\n";
-      } else {
-        InterfaceMaker::indent(out, indent_level) << "delete " << container << ";\n";
-      }
+      InterfaceMaker::indent(out, indent_level) << "delete " << container << ";\n";
     }
 
   } else if (_type == T_typecast_method) {
@@ -866,13 +860,12 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
     break;
 
   case T_constructor:
-    if (!_has_this && _parameters.size() == 1 &&
-        TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
-        TypeManager::unwrap(_return_type->get_orig_type())) {
-      // If this is the only parameter, and it's the same as the
-      // "this" type, this is a copy constructor.
+    if (_ftype->_flags & CPPFunctionType::F_copy_constructor) {
+      // It's a copy constructor.
       _flags |= F_copy_constructor;
 
+    } else if (_ftype->_flags & CPPFunctionType::F_move_constructor) {
+
     } 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.

Fichier diff supprimé car celui-ci est trop grand
+ 355 - 145
dtool/src/interrogate/interfaceMakerPythonNative.cxx


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

@@ -199,7 +199,7 @@ public:
   bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
   bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
   void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const InterrogateType &itype, bool is_const);
-  bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
+  bool HasAGetClassTypeFunction(CPPType *type);
   int NeedsAStrFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   bool NeedsARichCompareFunction(const InterrogateType &itype_class);

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

@@ -550,7 +550,7 @@ main(int argc, char **argv) {
 
     output_include
       << "/*\n"
-      << " * This file generated by:\n"
+      << " * This file was generated by:\n"
       << " * " << command_line << "\n"
       << " *\n"
       << " */\n\n";
@@ -572,7 +572,7 @@ main(int argc, char **argv) {
 
     output_code
       << "/*\n"
-      << " * This file generated by:\n"
+      << " * This file was generated by:\n"
       << " * " << command_line << "\n"
       << " *\n"
       << " */\n\n";

+ 31 - 23
dtool/src/interrogate/interrogateBuilder.cxx

@@ -53,7 +53,6 @@
 
 InterrogateBuilder builder;
 std::string EXPORT_IMPORT_PREFIX;
-bool inside_python_native = false;
 
 ////////////////////////////////////////////////////////////////////
 //     Function: InterrogateBuilder::add_source_file
@@ -1912,27 +1911,29 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
   CPPType *return_type = NULL;
 
   CPPFunctionGroup *fgroup = make_property->_getter;
-  CPPFunctionGroup::Instances::const_iterator fi;
-  for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
-    CPPInstance *function = (*fi);
-    CPPFunctionType *ftype =
-      function->_type->as_function_type();
-    if (ftype != NULL && ftype->_parameters->_parameters.size() == 0) {
-      getter = function;
-      return_type = ftype->_return_type;
-
-      // The return type of the non-const method probably better represents
-      // the type of the property we are creating.
-      if ((ftype->_flags & CPPFunctionType::F_const_method) == 0) {
-        break;
+  if (fgroup != NULL) {
+    CPPFunctionGroup::Instances::const_iterator fi;
+    for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
+      CPPInstance *function = (*fi);
+      CPPFunctionType *ftype =
+        function->_type->as_function_type();
+      if (ftype != NULL && ftype->_parameters->_parameters.size() == 0) {
+        getter = function;
+        return_type = ftype->_return_type;
+
+        // The return type of the non-const method probably better represents
+        // the type of the property we are creating.
+        if ((ftype->_flags & CPPFunctionType::F_const_method) == 0) {
+          break;
+        }
       }
     }
-  }
 
-  if (getter == NULL || return_type == NULL) {
-    cerr << "No instance of getter '"
-         << make_property->_getter->_name << "' is suitable!\n";
-    return 0;
+    if (getter == NULL || return_type == NULL) {
+      cerr << "No instance of getter '"
+           << fgroup->_name << "' is suitable!\n";
+      return 0;
+    }
   }
 
   InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
@@ -1944,11 +1945,17 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
   iproperty._name = make_property->get_simple_name();
   iproperty._scoped_name = descope(make_property->get_local_name(&parser));
 
-  iproperty._type = get_type(return_type, false);
+  if (return_type != NULL) {
+    iproperty._type = get_type(return_type, false);
+  } else {
+    iproperty._type = 0;
+  }
 
-  iproperty._flags |= InterrogateElement::F_has_getter;
-  iproperty._getter = get_function(getter, "", struct_type,
-                                   struct_type->get_scope(), 0);
+  if (getter != NULL) {
+    iproperty._flags |= InterrogateElement::F_has_getter;
+    iproperty._getter = get_function(getter, "", struct_type,
+                                     struct_type->get_scope(), 0);
+  }
 
   // See if there happens to be a comment before the MAKE_PROPERTY macro.
   if (make_property->_leading_comment != (CPPCommentBlock *)NULL) {
@@ -1958,6 +1965,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
   // Now look for setters.
   fgroup = make_property->_setter;
   if (fgroup != NULL) {
+    CPPFunctionGroup::Instances::const_iterator fi;
     for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
       CPPInstance *function = (*fi);
       iproperty._flags |= InterrogateElement::F_has_setter;

+ 53 - 2
dtool/src/interrogate/interrogate_module.cxx

@@ -25,6 +25,7 @@
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
 #include "pset.h"
+#include "vector_string.h"
 
 Filename output_code_filename;
 string module_name;
@@ -33,6 +34,7 @@ bool build_c_wrappers = false;
 bool build_python_wrappers = false;
 bool build_python_native_wrappers = false;
 bool track_interpreter = false;
+vector_string imports;
 
 // Short command-line options.
 static const char *short_options = "";
@@ -46,6 +48,7 @@ enum CommandOptions {
   CO_python,
   CO_python_native,
   CO_track_interpreter,
+  CO_import,
 };
 
 static struct option long_options[] = {
@@ -56,6 +59,7 @@ static struct option long_options[] = {
   { "python", no_argument, NULL, CO_python },
   { "python-native", no_argument, NULL, CO_python_native },
   { "track-interpreter", no_argument, NULL, CO_track_interpreter },
+  { "import", required_argument, NULL, CO_import },
   { NULL }
 };
 
@@ -113,6 +117,9 @@ int write_python_table_native(ostream &out) {
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     printf("Referencing Library %s\n", (*ii).c_str());
     out << "extern 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";
   }
 
   out << "\n"
@@ -138,6 +145,19 @@ int write_python_table_native(ostream &out) {
     out << "  in_interpreter = 1;\n";
   }
 
+  vector_string::const_iterator si;
+  for (si = imports.begin(); si != imports.end(); ++si) {
+    out << "  PyImport_Import(PyUnicode_FromString(\"" << *si << "\"));\n";
+  }
+
+  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[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
@@ -145,7 +165,15 @@ int write_python_table_native(ostream &out) {
 
   out << "NULL};\n"
       << "\n"
-      << "  return Dtool_PyModuleInitHelper(defs, &py_" << library_name << "_module);\n"
+      << "  PyObject *module = Dtool_PyModuleInitHelper(defs, &py_" << library_name << "_module);\n"
+      << "  if (module != NULL) {\n";
+
+  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
+    out << "    Dtool_" << *ii << "_BuildInstants(module);\n";
+  }
+
+  out << "  }\n"
+      << "  return module;\n"
       << "}\n"
       << "\n"
       << "#else  // Python 2 case\n"
@@ -162,6 +190,18 @@ int write_python_table_native(ostream &out) {
     out << "  in_interpreter = 1;\n";
   }
 
+  for (si = imports.begin(); si != imports.end(); ++si) {
+    out << "  PyImport_Import(PyUnicode_FromString(\"" << *si << "\"));\n";
+  }
+
+  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[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
@@ -169,7 +209,14 @@ int write_python_table_native(ostream &out) {
 
   out << "NULL};\n"
       << "\n"
-      << "  Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n"
+      << "  PyObject *module = Dtool_PyModuleInitHelper(defs, \"" << module_name << "\");\n"
+      << "  if (module != NULL) {\n";
+
+  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
+    out << "    Dtool_" << *ii << "_BuildInstants(module);\n";
+  }
+
+  out << "  }\n"
       << "}\n"
       << "#endif\n"
       << "\n";
@@ -335,6 +382,10 @@ int main(int argc, char *argv[]) {
       track_interpreter = true;
       break;
 
+    case CO_import:
+      imports.push_back(optarg);
+      break;
+
     default:
       exit(1);
     }

+ 56 - 1
dtool/src/interrogate/typeManager.cxx

@@ -2570,4 +2570,59 @@ is_local(CPPType *source_type) {
 
  return false;
  */
-};
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_trivial
+//       Access: Public, Static
+//  Description: Returns true if the type is trivial (or trivial
+//               enough for our purposes).
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_trivial(CPPType *source_type) {
+  switch (source_type->get_subtype()) {
+  case CPPDeclaration::ST_const:
+    return is_trivial(source_type->as_const_type()->_wrapped_around);
+
+  case CPPDeclaration::ST_reference:
+    return false;
+
+  case CPPDeclaration::ST_pointer:
+    return true;
+
+  case CPPDeclaration::ST_simple:
+    return true;
+
+  case CPPDeclaration::ST_typedef:
+    return is_trivial(source_type->as_typedef_type()->_type);
+
+  default:
+    if (source_type->is_trivial()) {
+      return true;
+    } else {
+      // This is a bit of a hack.  is_trivial() returns false for types that
+      // have an empty constructor (since we can't use =default yet).
+      // For the other classes, it's just convenient to consider them trivial
+      // even if they aren't, since they are simple enough.
+      string name = source_type->get_simple_name();
+      return (name == "ButtonHandle" || name == "DatagramIterator" ||
+              name == "BitMask" || name == "Filename" || name == "pixel" ||
+              name == "NodePath" || name == "LoaderOptions" ||
+              name == "PointerToArray" || name == "ConstPointerToArray" ||
+              name == "PStatThread" ||
+              (name.size() >= 6 && name.substr(0, 6) == "LPlane") ||
+              (name.size() > 6 && name.substr(0, 6) == "LPoint") ||
+              (name.size() > 7 && name.substr(0, 7) == "LVector") ||
+              (name.size() > 7 && name.substr(0, 7) == "LMatrix") ||
+              (name.size() > 8 && name.substr(0, 8) == "LVecBase") ||
+              (name.size() >= 9 && name.substr(0, 9) == "LParabola") ||
+              (name.size() >= 9 && name.substr(0, 9) == "LRotation") ||
+              (name.size() >= 11 && name.substr(0, 11) == "LQuaternion") ||
+              (name.size() >= 12 && name.substr(0, 12) == "LOrientation") ||
+              (name.size() > 16 && name.substr(0, 16) == "UnalignedLMatrix") ||
+              (name.size() > 17 && name.substr(0, 17) == "UnalignedLVecBase"));
+    }
+  }
+
+  return false;
+}

+ 1 - 1
dtool/src/interrogate/typeManager.h

@@ -146,7 +146,7 @@ public:
 
   static bool is_exported(CPPType *type);
   static bool is_local(CPPType *type);
-
+  static bool is_trivial(CPPType *type);
 };
 
 #endif

+ 12 - 9
dtool/src/interrogatedb/dtool_super_base.cxx

@@ -21,7 +21,7 @@ class EmptyClass {
 Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
 
 static PyObject *GetSuperBase(PyObject *self) {
-  Py_INCREF(&(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject())); // order is important .. this is used for static functions
+  Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
   return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
 };
 
@@ -35,21 +35,21 @@ EXPCL_DTOOLCONFIG void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module
   if (!initdone) {
 
     initdone = true;
-    Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict = PyDict_New();
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict);
+    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(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()) < 0) {
+    if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
       PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
       return;
     }
-    Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
+    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
 
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], &Dtool_DTOOL_SUPER_BASE.As_PyObject()));
+    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
   }
 
   if (module != NULL) {
-    Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
-    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
+    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
+    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
   }
 }
 
@@ -123,9 +123,12 @@ EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
     0,
     0,
   },
+  TypeHandle::none(),
+  Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
   Dtool_UpcastInterface_DTOOL_SUPER_BASE,
   Dtool_DowncastInterface_DTOOL_SUPER_BASE,
-  TypeHandle::none(),
+  NULL,
+  NULL,
 };
 
 #endif  // HAVE_PYTHON

+ 0 - 20
dtool/src/interrogatedb/interrogateType.cxx

@@ -269,23 +269,3 @@ remap_indices(const IndexRemapper &remap) {
   }
 
 }
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: GetRunTimeDictionary
-////////////////////////////////////////////////////////////////////
-EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary()
-{
-    static RunTimeTypeDictionary dict;
-    return dict;
-};
-
-////////////////////////////////////////////////////////////////////
-//     Function: GetRunTimeTypeList
-////////////////////////////////////////////////////////////////////
-EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList()
-{
-    static RunTimeTypeList list;
-    return list;
-};
-

+ 0 - 10
dtool/src/interrogatedb/interrogateType.h

@@ -231,14 +231,4 @@ INLINE istream &operator >> (istream &in, InterrogateType::EnumValue &d);
 
 #include "interrogateType.I"
 
-#include <set>
-#include <map>
-struct Dtool_PyTypedObject;
-typedef std::map< int , Dtool_PyTypedObject *>   RunTimeTypeDictionary;
-typedef std::set<int >                           RunTimeTypeList;
-
-EXPCL_DTOOLCONFIG  RunTimeTypeDictionary & GetRunTimeDictionary();
-EXPCL_DTOOLCONFIG  RunTimeTypeList & GetRunTimeTypeList();
-
-
 #endif

+ 122 - 54
dtool/src/interrogatedb/py_panda.cxx

@@ -26,6 +26,10 @@ PyMemberDef standard_type_members[] = {
   {NULL}  /* Sentinel */
 };
 
+static RuntimeTypeMap runtime_type_map;
+static RuntimeTypeSet runtime_type_set;
+static NamedTypeMap named_type_map;
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DtoolCanThisBeAPandaInstance
 //  Description: Given a valid (non-NULL) PyObject, does a simple
@@ -273,6 +277,29 @@ PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *functio
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Dtool_Raise_AttributeError
+//  Description: Raises an AttributeError of the form:
+//               'type' has no attribute 'attr'
+//
+//               Always returns NULL so that it can be conveniently
+//               used as a return expression for wrapper functions
+//               that return a PyObject pointer.
+////////////////////////////////////////////////////////////////////
+PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute) {
+#if PY_MAJOR_VERSION >= 3
+  PyObject *message = PyUnicode_FromFormat(
+#else
+  PyObject *message = PyString_FromFormat(
+#endif
+    "'%.100s' object has no attribute '%.200s'",
+    Py_TYPE(obj)->tp_name, attribute);
+
+  Py_INCREF(PyExc_TypeError);
+  PyErr_Restore(PyExc_TypeError, message, (PyObject *)NULL);
+  return NULL;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Dtool_Raise_BadArgumentsError
 //  Description: Raises a TypeError of the form:
@@ -330,6 +357,24 @@ PyObject *Dtool_Return_Bool(bool value) {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Dtool_Return
+//  Description: Convenience method that checks for exceptions, and
+//               if one occurred, returns NULL, otherwise the given
+//               return value.  Its reference count is not increased.
+////////////////////////////////////////////////////////////////////
+PyObject *_Dtool_Return(PyObject *value) {
+  if (_PyErr_OCCURRED()) {
+    return NULL;
+  }
+#ifndef NDEBUG
+  if (Notify::ptr()->has_assert_failed()) {
+    return Dtool_Raise_AssertionError();
+  }
+#endif
+  return value;
+}
+
 ////////////////////////////////////////////////////////////////////////
 //  Function : DTool_CreatePyInstanceTyped
 //
@@ -360,7 +405,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
         /////////////////////////////////////////////
         // ask class to allocate an instance..
         /////////////////////////////////////////////
-        Dtool_PyInstDef *self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL, NULL);
+        Dtool_PyInstDef *self = (Dtool_PyInstDef *) target_class->_PyType.tp_new(&target_class->_PyType, NULL, NULL);
         if (self != NULL) {
           self->_ptr_to_object = new_local_this;
           self->_memory_rules = memory_rules;
@@ -377,7 +422,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
   // if we get this far .. just wrap the thing in the known type ??
   //    better than aborting...I guess....
   /////////////////////////////////////////////////////
-  Dtool_PyInstDef *self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL);
+  Dtool_PyInstDef *self = (Dtool_PyInstDef *) known_class_type._PyType.tp_new(&known_class_type._PyType, NULL, NULL);
   if (self != NULL) {
     self->_ptr_to_object = local_this_in;
     self->_memory_rules = memory_rules;
@@ -401,7 +446,7 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
   }
 
   Dtool_PyTypedObject *classdef = &in_classdef;
-  Dtool_PyInstDef *self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL, NULL);
+  Dtool_PyInstDef *self = (Dtool_PyInstDef *) classdef->_PyType.tp_new(&classdef->_PyType, NULL, NULL);
   if (self != NULL) {
     self->_ptr_to_object = local_this;
     self->_memory_rules = memory_rules;
@@ -446,42 +491,97 @@ void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
 //
 ///////////////////////////////////////////////////////////////////////////////
 void
-RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id) {
-  if (class_id == 0) {
+RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) {
+  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
+      << "Class " << otype._PyType.tp_name
       << " has a zero TypeHandle value; check that init_type() is called.\n";
 
-  } else if (class_id > 0) {
-    RunTimeTypeDictionary &dict = GetRunTimeDictionary();
-    pair<RunTimeTypeDictionary::iterator, bool> result =
-      dict.insert(RunTimeTypeDictionary::value_type(class_id, otype));
+  } 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 {
+    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 class_id.
+      // 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
+        << "Classes " << otype._PyType.tp_name
         << " and " << other_type->_PyType.tp_name
-        << " share the same TypeHandle value (" << class_id
+        << " share the same TypeHandle value (" << type_index
         << "); check class definitions.\n";
 
     } else {
-      GetRunTimeTypeList().insert(class_id);
-      otype->_type = TypeRegistry::ptr()->find_type_by_id(class_id);
+      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 NULL;
+  } 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 NULL;
+  } else {
+    return it->second;
   }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
-  RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type);
-  if (di != GetRunTimeDictionary().end()) {
+  RuntimeTypeMap::iterator di = runtime_type_map.find(type);
+  if (di != runtime_type_map.end()) {
     return di->second;
   } else {
-    int type2 = get_best_parent_from_Set(type, GetRunTimeTypeList());
-    di = GetRunTimeDictionary().find(type2);
-    if (di != GetRunTimeDictionary().end()) {
+    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;
     }
   }
@@ -526,11 +626,6 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
 #endif
   }
 
-  // the constant inits... enums, classes ...
-  for (int y = 0; defs[y] != NULL; y++) {
-    defs[y]->_constants(module);
-  }
-
   PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);
   return module;
 }
@@ -710,39 +805,12 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
   return PyBool_FromLong(result);
 }
 
-PyObject *make_list_for_item(PyObject *self, const char *num_name,
-                             const char *element_name) {
-  PyObject *num_result = PyObject_CallMethod(self, (char *)num_name, (char *)"()");
-  if (num_result == NULL) {
-    return NULL;
-  }
-
-  Py_ssize_t num_elements;
-#if PY_MAJOR_VERSION >= 3
-  num_elements = PyLong_AsSsize_t(num_result);
-#else
-  num_elements = PyInt_AsSsize_t(num_result);
-#endif
-  Py_DECREF(num_result);
-
-  PyObject *list = PyList_New(num_elements);
-  for (int i = 0; i < num_elements; ++i) {
-    PyObject *element = PyObject_CallMethod(self, (char *)element_name, (char *)"(i)", i);
-    if (element == NULL) {
-      Py_DECREF(list);
-      return NULL;
-    }
-    PyList_SET_ITEM(list, i, element);
-  }
-  return list;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: copy_from_make_copy
 //  Description: This is a support function for a synthesized
 //               __copy__() method from a C++ make_copy() method.
 ////////////////////////////////////////////////////////////////////
-PyObject *copy_from_make_copy(PyObject *self) {
+PyObject *copy_from_make_copy(PyObject *self, PyObject *noargs) {
   return PyObject_CallMethod(self, (char *)"make_copy", (char *)"()");
 }
 
@@ -751,7 +819,7 @@ PyObject *copy_from_make_copy(PyObject *self) {
 //  Description: This is a support function for a synthesized
 //               __copy__() method from a C++ copy constructor.
 ////////////////////////////////////////////////////////////////////
-PyObject *copy_from_copy_constructor(PyObject *self) {
+PyObject *copy_from_copy_constructor(PyObject *self, PyObject *noargs) {
   PyObject *this_class = PyObject_Type(self);
   if (this_class == NULL) {
     return NULL;

+ 30 - 29
dtool/src/interrogatedb/py_panda.h

@@ -143,17 +143,17 @@ using namespace std;
 ///////////////////////////////////////////////////////////////////////////////////
 
 struct Dtool_PyTypedObject;
-typedef std::map<int, Dtool_PyTypedObject *>   RunTimeTypeDictionary;
-typedef std::set<int>                           RunTimeTypeList;
-
-EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary();
-EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList();
+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
 typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *);
 typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
+typedef void *(*CoerceFunction)(PyObject *, void *);
+typedef void (*ModuleClassInitFunction)(PyObject *module);
 
 //inline          Dtool_PyTypedObject *  Dtool_RuntimeTypeDtoolType(int type);
 //inline void     Dtool_Deallocate_General(PyObject * self);
@@ -196,16 +196,16 @@ struct Dtool_PyTypedObject {
   // Standard Python Features..
   PyTypeObject _PyType;
 
-  // My Class Level Features..
-  UpcastFunction _Dtool_UpcastInterface;    // The Upcast Function By Slot
-  DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
-
   // May be TypeHandle::none() to indicate a non-TypedObject class.
   TypeHandle _type;
 
-  // some convenience functions..
-  inline PyTypeObject &As_PyTypeObject() { return _PyType; };
-  inline PyObject &As_PyObject() { return (PyObject &)_PyType; };
+  ModuleClassInitFunction _Dtool_ModuleClassInit;
+
+  UpcastFunction _Dtool_UpcastInterface;    // The Upcast Function By Slot
+  DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
+
+  CoerceFunction _Dtool_ConstCoerce;
+  CoerceFunction _Dtool_Coerce;
 };
 
 // This is now simply a forward declaration.  The actual definition is created
@@ -217,7 +217,7 @@ struct Dtool_PyTypedObject {
 //  More Macro(s) to Implement class functions.. Usually used if C++ needs type information
 ////////////////////////////////////////////////////////////////////////
 #define Define_Dtool_new(CLASS_NAME,CNAME)\
-PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
+static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
   (void) args; (void) kwds;\
   PyObject *self = type->tp_alloc(type, 0);\
   ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
@@ -291,7 +291,11 @@ EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self);
 //
 ///////////////////////////////////////////////////////////////////////////////
 
-EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id);
+EXPCL_DTOOLCONFIG void RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype);
+EXPCL_DTOOLCONFIG void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype);
+
+EXPCL_DTOOLCONFIG Dtool_PyTypedObject *LookupNamedClass(const string &name);
+EXPCL_DTOOLCONFIG Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle);
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
@@ -305,7 +309,7 @@ EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
 //      with these as the generated code depends on how this is set
 //      up..
 ////////////////////////////////////////////////////////////////////////
-EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer);
+EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
 
 EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, bool report_errors);
 
@@ -340,6 +344,7 @@ EXPCL_DTOOLCONFIG bool Dtool_CheckErrorOccurred();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AssertionError();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_TypeError(const char *message);
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
+EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
 
 EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
 #ifdef NDEBUG
@@ -352,11 +357,14 @@ EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
 
 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return_None();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Return_Bool(bool value);
+EXPCL_DTOOLCONFIG PyObject *_Dtool_Return(PyObject *value);
 
 #ifdef NDEBUG
 #define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
+#define Dtool_Return(value) (_PyErr_OCCURRED() != NULL ? NULL : value)
 #else
 #define Dtool_Return_None() _Dtool_Return_None()
+#define Dtool_Return(value) _Dtool_Return(value)
 #endif
 
 ////////////////////////////////////////////////////////////////////////
@@ -407,11 +415,9 @@ template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memo
 //struct Dtool_PyTypedObject Dtool_##CLASS_NAME;
 
 #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
-extern EXPORT_THIS   Dtool_PyTypedObject Dtool_##CLASS_NAME;\
-int         Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
-PyObject *  Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
-void  *     Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
-void  *     Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);
+extern struct Dtool_PyTypedObject Dtool_##CLASS_NAME;\
+static int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
+static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);
 
 ///////////////////////////////////////////////////////////////////////////////
 #define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
@@ -460,10 +466,7 @@ EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &them
 /// fallowing structors and code.. along with the support of interigate_module
 ///////////////////////////////////////////////////////////////////////////////
 struct LibraryDef {
-  typedef void (*ConstantFunction)(PyObject *);
-
   PyMethodDef *_methods;
-  ConstantFunction _constants;
 };
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -506,14 +509,10 @@ EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
 EXPCL_DTOOLCONFIG PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op);
 
 EXPCL_DTOOLCONFIG PyObject *
-make_list_for_item(PyObject *self, const char *num_name,
-                   const char *element_name);
+copy_from_make_copy(PyObject *self, PyObject *noargs);
 
 EXPCL_DTOOLCONFIG PyObject *
-copy_from_make_copy(PyObject *self);
-
-EXPCL_DTOOLCONFIG PyObject *
-copy_from_copy_constructor(PyObject *self);
+copy_from_copy_constructor(PyObject *self, PyObject *noargs);
 
 EXPCL_DTOOLCONFIG PyObject *
 map_deepcopy_to_copy(PyObject *self, PyObject *args);
@@ -527,6 +526,8 @@ PyLongOrInt_FromUnsignedLong(unsigned long value);
 EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
 EXPCL_DTOOLCONFIG extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
 
+#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
+
 #endif  // HAVE_PYTHON && !CPPPARSER
 
 #endif // PY_PANDA_H_

+ 3 - 0
dtool/src/parser-inc/iostream

@@ -43,6 +43,9 @@ __published:
   static const openmode in;
   static const openmode out;
   static const openmode trunc;
+protected:
+  // Force this to be a non-trivial type.
+  ios_base() {};
 };
 class ios : public ios_base {
 __published:

+ 0 - 2
dtool/src/parser-inc/stdtypedefs.h

@@ -44,7 +44,5 @@ typedef unsigned char uchar;
 #define NULL ((void *)0)
 #endif
 
-typedef int fd_set;
-
 #endif
 

+ 48 - 43
makepanda/makepanda.py

@@ -87,7 +87,7 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "ODE", "PHYSX", "BULLET", "PANDAPHYSICS",            # Physics
   "SPEEDTREE",                                         # SpeedTree
   "ZLIB", "PNG", "JPEG", "TIFF", "SQUISH", "FREETYPE", # 2D Formats support
-  ] + MAYAVERSIONS + MAXVERSIONS + [ "FCOLLADA",       # 3D Formats support
+  ] + MAYAVERSIONS + MAXVERSIONS + [ "FCOLLADA", "ASSIMP", # 3D Formats support
   "VRPN", "OPENSSL",                                   # Transport
   "FFTW",                                              # Algorithm helpers
   "ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION",        # Augmented Reality
@@ -367,7 +367,7 @@ if RUNTIME or RTDIST:
 if DEBVERSION is None:
     DEBVERSION = VERSION
 
-MAJOR_VERSION = VERSION[:3]
+MAJOR_VERSION = '.'.join(VERSION.split('.')[:2])
 
 if P3DSUFFIX is None:
     P3DSUFFIX = MAJOR_VERSION
@@ -595,6 +595,7 @@ if (COMPILER == "MSVC"):
     if (PkgSkip("FFTW")==0):     LibName("FFTW",     GetThirdpartyDir() + "fftw/lib/fftw.lib")
     if (PkgSkip("ARTOOLKIT")==0):LibName("ARTOOLKIT",GetThirdpartyDir() + "artoolkit/lib/libAR.lib")
     if (PkgSkip("FCOLLADA")==0): LibName("FCOLLADA", GetThirdpartyDir() + "fcollada/lib/FCollada.lib")
+    if (PkgSkip("ASSIMP")==0):   PkgDisable("ASSIMP")  # Not yet supported
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/cv.lib")
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/highgui.lib")
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/cvaux.lib")
@@ -737,6 +738,7 @@ if (COMPILER=="GCC"):
         SmartPkgEnable("EIGEN",     "eigen3",    (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
         SmartPkgEnable("ARTOOLKIT", "",          ("AR"), "AR/ar.h")
         SmartPkgEnable("FCOLLADA",  "",          ChooseLib(fcollada_libs, "FCOLLADA"), ("FCollada", "FCollada/FCollada.h"))
+        SmartPkgEnable("ASSIMP",    "assimp", ("assimp"), "assimp")
         SmartPkgEnable("FFMPEG",    ffmpeg_libs, ffmpeg_libs, ffmpeg_libs)
         SmartPkgEnable("SWSCALE",   "libswscale", "libswscale", ("libswscale", "libswscale/swscale.h"), target_pkg = "FFMPEG")
         SmartPkgEnable("SWRESAMPLE","libswresample", "libswresample", ("libswresample", "libswresample/swresample.h"), target_pkg = "FFMPEG")
@@ -913,9 +915,19 @@ if (COMPILER=="GCC"):
 
 DefSymbol("WITHINPANDA", "WITHIN_PANDA", "1")
 if GetLinkAllStatic():
-    DefSymbol("ALWAYS", "LINK_ALL_STATIC", "")
+    DefSymbol("ALWAYS", "LINK_ALL_STATIC")
 if GetTarget() == 'android':
-    DefSymbol("ALWAYS", "ANDROID", "")
+    DefSymbol("ALWAYS", "ANDROID")
+
+if not PkgSkip("EIGEN"):
+    DefSymbol("ALWAYS", "EIGEN_MPL2_ONLY")
+    if GetOptimize() >= 3:
+        DefSymbol("ALWAYS", "EIGEN_NO_DEBUG")
+        if COMPILER == "MSVC":
+            # Squeeze out a bit more performance on MSVC builds...
+            # Only do this if EIGEN_NO_DEBUG is also set, otherwise it
+            # will turn them into runtime assertions.
+            DefSymbol("ALWAYS", "EIGEN_NO_STATIC_ASSERT")
 
 ########################################################################
 ##
@@ -1018,10 +1030,10 @@ def CompileCxx(obj,src,opts):
 
             if (optlevel==1): cmd += " /MDd /Zi /RTCs /GS"
             if (optlevel==2): cmd += " /MDd /Zi"
-            if (optlevel==3): cmd += " /MD /Zi /O2 /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING"
+            if (optlevel==3): cmd += " /MD /Zi /GS- /O2 /Ob2 /Oi /Ot /fp:fast"
             if (optlevel==4):
-               cmd += " /MD /Zi /Ox /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING /DNDEBUG /GL"
-               cmd += " /Oy /Zp16"      # jean-claude add /Zp16 insures correct static alignment for SSEx
+                cmd += " /MD /Zi /GS- /Ox /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING /DNDEBUG /GL"
+                cmd += " /Oy /Zp16"      # jean-claude add /Zp16 insures correct static alignment for SSEx
 
             cmd += " /Fd" + os.path.splitext(obj)[0] + ".pdb"
 
@@ -1036,7 +1048,7 @@ def CompileCxx(obj,src,opts):
             if 'EXCEPTIONS' in opts:
                 cmd += " /EHsc"
             else:
-                cmd += " -D_HAS_EXCEPTIONS=0"
+                cmd += " /D_HAS_EXCEPTIONS=0"
 
             if 'RTTI' not in opts:
                  cmd += " /GR-"
@@ -1402,7 +1414,10 @@ def CompileImod(wobj, wsrc, opts):
         # Assume that interrogate_module is on the PATH somewhere.
         cmd = 'interrogate_module'
 
-    cmd += ' -oc ' + woutc + ' -module ' + module + ' -library ' + library + ' -python-native '
+    cmd += ' -oc ' + woutc + ' -module ' + module + ' -library ' + library + ' -python-native'
+    importmod = GetValueOption(opts, "IMPORT:")
+    if importmod:
+        cmd += ' -import ' + importmod
     for x in wsrc: cmd += ' ' + BracketNameWithQuotes(x)
     oscmd(cmd)
     CompileCxx(wobj,woutc,opts)
@@ -1583,20 +1598,13 @@ def CompileLink(dll, obj, opts):
                 cmd = cxx + ' -undefined dynamic_lookup'
                 if ("BUNDLE" in opts): cmd += ' -bundle '
                 else:
-                    if GetOrigExt(dll) == ".pyd":
-                        install_name = '@loader_path/../panda3d/' + os.path.basename(dll)
-                    else:
-                        install_name = os.path.basename(dll)
+                    install_name = os.path.basename(dll)
                     cmd += ' -dynamiclib -install_name ' + install_name
                     cmd += ' -compatibility_version ' + MAJOR_VERSION + ' -current_version ' + VERSION
                 cmd += ' -o ' + dll + ' -L' + GetOutputDir() + '/lib -L' + GetOutputDir() + '/tmp'
             else:
                 cmd = cxx + ' -shared'
                 if ("MODULE" not in opts): cmd += " -Wl,-soname=" + os.path.basename(dll)
-                if GetOrigExt(dll) == ".pyd" and not os.path.basename(dll).startswith('core'):
-                    # Tell the other libraries where to find core.so.
-                    # Not sure if this is the best way to do that, but it works.
-                    cmd += " -Wl,-rpath '-Wl,$ORIGIN'"
                 cmd += ' -o ' + dll + ' -L' + GetOutputDir() + '/lib -L' + GetOutputDir() + '/tmp'
 
         if GetTarget() == 'emscripten' and GetOrigExt(dll) != ".exe":
@@ -3873,12 +3881,11 @@ if (PkgSkip("VISION") == 0) and (not RUNTIME):
 
   TargetAdd('vision_module.obj', input='libp3vision.in')
   TargetAdd('vision_module.obj', opts=OPTS)
-  TargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision'])
+  TargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision', 'IMPORT:panda3d.core'])
 
   TargetAdd('vision.pyd', input='vision_module.obj')
   TargetAdd('vision.pyd', input='libp3vision_igate.obj')
   TargetAdd('vision.pyd', input='libp3vision.dll')
-  TargetAdd('vision.pyd', input='core.pyd')
   TargetAdd('vision.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('vision.pyd', opts=['PYTHON'])
 
@@ -3904,13 +3911,12 @@ if (PkgSkip("ROCKET") == 0) and (not RUNTIME):
 
   TargetAdd('rocket_module.obj', input='libp3rocket.in')
   TargetAdd('rocket_module.obj', opts=OPTS)
-  TargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket'])
+  TargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket', 'IMPORT:panda3d.core'])
 
   TargetAdd('rocket.pyd', input='rocket_module.obj')
   TargetAdd('rocket.pyd', input='libp3rocket_igate.obj')
   TargetAdd('rocket.pyd', input='p3rocket_rocketRegion_ext.obj')
   TargetAdd('rocket.pyd', input='libp3rocket.dll')
-  TargetAdd('rocket.pyd', input='core.pyd')
   TargetAdd('rocket.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('rocket.pyd', opts=['PYTHON', 'ROCKET'])
 
@@ -3932,12 +3938,11 @@ if PkgSkip("AWESOMIUM") == 0 and not RUNTIME:
 
   TargetAdd('awesomium_module.obj', input='libp3awesomium.in')
   TargetAdd('awesomium_module.obj', opts=OPTS)
-  TargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium'])
+  TargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium', 'IMPORT:panda3d.core'])
 
   TargetAdd('awesomium.pyd', input='awesomium_module.obj')
   TargetAdd('awesomium.pyd', input='libp3awesomium_igate.obj')
   TargetAdd('awesomium.pyd', input='libp3awesomium.dll')
-  TargetAdd('awesomium.pyd', input='core.pyd')
   TargetAdd('awesomium.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('awesomium.pyd', opts=['PYTHON'])
 
@@ -3966,12 +3971,11 @@ if (PkgSkip('SKEL')==0) and (not RUNTIME):
   TargetAdd('libpandaskel.dll', opts=OPTS)
 
   TargetAdd('skel_module.obj', input='libp3skel.in')
-  TargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel'])
+  TargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel', 'IMPORT:panda3d.core'])
 
   TargetAdd('skel.pyd', input='skel_module.obj')
   TargetAdd('skel.pyd', input='libp3skel_igate.obj')
   TargetAdd('skel.pyd', input='libpandaskel.dll')
-  TargetAdd('skel.pyd', input='core.pyd')
   TargetAdd('skel.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('skel.pyd', opts=['PYTHON'])
 
@@ -4005,12 +4009,11 @@ if (PkgSkip('PANDAFX')==0) and (not RUNTIME):
   OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG']
   TargetAdd('fx_module.obj', input='libp3distort.in')
   TargetAdd('fx_module.obj', opts=OPTS)
-  TargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx'])
+  TargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx', 'IMPORT:panda3d.core'])
 
   TargetAdd('fx.pyd', input='fx_module.obj')
   TargetAdd('fx.pyd', input='libp3distort_igate.obj')
   TargetAdd('fx.pyd', input='libpandafx.dll')
-  TargetAdd('fx.pyd', input='core.pyd')
   TargetAdd('fx.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('fx.pyd', opts=['PYTHON'])
 
@@ -4033,12 +4036,11 @@ if (PkgSkip("VRPN")==0 and not RUNTIME):
 
   TargetAdd('vrpn_module.obj', input='libp3vrpn.in')
   TargetAdd('vrpn_module.obj', opts=OPTS)
-  TargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn'])
+  TargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn', 'IMPORT:panda3d.core'])
 
   TargetAdd('vrpn.pyd', input='vrpn_module.obj')
   TargetAdd('vrpn.pyd', input='libp3vrpn_igate.obj')
   TargetAdd('vrpn.pyd', input='libp3vrpn.dll')
-  TargetAdd('vrpn.pyd', input='core.pyd')
   TargetAdd('vrpn.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('vrpn.pyd', opts=['PYTHON'])
 
@@ -4266,14 +4268,13 @@ if (not RUNTIME):
   TargetAdd('egg_module.obj', input='libp3egg2pg.in')
   TargetAdd('egg_module.obj', input='libp3egg.in')
   TargetAdd('egg_module.obj', opts=OPTS)
-  TargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg'])
+  TargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg', 'IMPORT:panda3d.core'])
 
   TargetAdd('egg.pyd', input='egg_module.obj')
   TargetAdd('egg.pyd', input='p3egg_eggGroupNode_ext.obj')
   TargetAdd('egg.pyd', input='libp3egg_igate.obj')
   TargetAdd('egg.pyd', input='libp3egg2pg_igate.obj')
   TargetAdd('egg.pyd', input='libpandaegg.dll')
-  TargetAdd('egg.pyd', input='core.pyd')
   TargetAdd('egg.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('egg.pyd', opts=['PYTHON'])
 
@@ -4450,13 +4451,12 @@ if (PkgSkip("ODE")==0 and not RUNTIME):
   OPTS=['DIR:panda/metalibs/pandaode', 'ODE']
   TargetAdd('ode_module.obj', input='libpandaode.in')
   TargetAdd('ode_module.obj', opts=OPTS)
-  TargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode'])
+  TargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode', 'IMPORT:panda3d.core'])
 
   TargetAdd('ode.pyd', input='ode_module.obj')
   TargetAdd('ode.pyd', input='libpandaode_igate.obj')
   TargetAdd('ode.pyd', input='p3ode_ext_composite.obj')
   TargetAdd('ode.pyd', input='libpandaode.dll')
-  TargetAdd('ode.pyd', input='core.pyd')
   TargetAdd('ode.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('ode.pyd', opts=['PYTHON', 'WINUSER', 'ODE'])
 
@@ -4488,12 +4488,11 @@ if (PkgSkip("BULLET")==0 and not RUNTIME):
   OPTS=['DIR:panda/metalibs/pandabullet', 'BULLET']
   TargetAdd('bullet_module.obj', input='libpandabullet.in')
   TargetAdd('bullet_module.obj', opts=OPTS)
-  TargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet'])
+  TargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet', 'IMPORT:panda3d.core'])
 
   TargetAdd('bullet.pyd', input='bullet_module.obj')
   TargetAdd('bullet.pyd', input='libpandabullet_igate.obj')
   TargetAdd('bullet.pyd', input='libpandabullet.dll')
-  TargetAdd('bullet.pyd', input='core.pyd')
   TargetAdd('bullet.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('bullet.pyd', opts=['PYTHON', 'WINUSER', 'BULLET'])
 
@@ -4527,12 +4526,11 @@ if (PkgSkip("PHYSX")==0):
   OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC']
   TargetAdd('physx_module.obj', input='libpandaphysx.in')
   TargetAdd('physx_module.obj', opts=OPTS)
-  TargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx'])
+  TargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx', 'IMPORT:panda3d.core'])
 
   TargetAdd('physx.pyd', input='physx_module.obj')
   TargetAdd('physx.pyd', input='libpandaphysx_igate.obj')
   TargetAdd('physx.pyd', input='libpandaphysx.dll')
-  TargetAdd('physx.pyd', input='core.pyd')
   TargetAdd('physx.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('physx.pyd', opts=['PYTHON', 'WINUSER', 'PHYSX', 'NOARCH:PPC'])
 
@@ -4593,14 +4591,13 @@ if (PkgSkip("PANDAPHYSICS")==0) and (not RUNTIME):
   if (PkgSkip("PANDAPARTICLESYSTEM")==0):
     TargetAdd('physics_module.obj', input='libp3particlesystem.in')
   TargetAdd('physics_module.obj', opts=OPTS)
-  TargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics'])
+  TargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics', 'IMPORT:panda3d.core'])
 
   TargetAdd('physics.pyd', input='physics_module.obj')
   TargetAdd('physics.pyd', input='libp3physics_igate.obj')
   if (PkgSkip("PANDAPARTICLESYSTEM")==0):
     TargetAdd('physics.pyd', input='libp3particlesystem_igate.obj')
   TargetAdd('physics.pyd', input='libpandaphysics.dll')
-  TargetAdd('physics.pyd', input='core.pyd')
   TargetAdd('physics.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('physics.pyd', opts=['PYTHON'])
 
@@ -4854,7 +4851,7 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('direct_module.obj', input='libp3interval.in')
   TargetAdd('direct_module.obj', input='libp3distributed.in')
   TargetAdd('direct_module.obj', opts=OPTS)
-  TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct'])
+  TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct', 'IMPORT:panda3d.core'])
 
   TargetAdd('direct.pyd', input='libp3dcparser_igate.obj')
   TargetAdd('direct.pyd', input='libp3showbase_igate.obj')
@@ -4864,7 +4861,6 @@ if (PkgSkip("DIRECT")==0):
 
   TargetAdd('direct.pyd', input='direct_module.obj')
   TargetAdd('direct.pyd', input='libp3direct.dll')
-  TargetAdd('direct.pyd', input='core.pyd')
   TargetAdd('direct.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('direct.pyd', opts=['PYTHON', 'OPENSSL', 'WINUSER', 'WINGDI'])
 
@@ -5257,6 +5253,16 @@ if (PkgSkip("PANDATOOL")==0 and PkgSkip("FCOLLADA")==0):
   TargetAdd('libp3daeegg.lib', input='p3daeegg_composite1.obj')
   TargetAdd('libp3daeegg.lib', opts=['FCOLLADA', 'CARBON'])
 
+#
+# DIRECTORY: pandatool/src/assimp
+#
+if (PkgSkip("PANDATOOL") == 0 and PkgSkip("ASSIMP")==0):
+  OPTS=['DIR:pandatool/src/assimp', 'ASSIMP', 'MODULE']
+  TargetAdd('p3assimp_composite1.obj', opts=OPTS, input='p3assimp_composite1.cxx')
+  TargetAdd('libp3assimp.dll', input='p3assimp_composite1.obj')
+  TargetAdd('libp3assimp.dll', input=COMMON_PANDA_LIBS)
+  TargetAdd('libp3assimp.dll', opts=OPTS)
+
 #
 # DIRECTORY: pandatool/src/daeprogs/
 #
@@ -6054,12 +6060,11 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME):
 
   TargetAdd('ai_module.obj', input='libpandaai.in')
   TargetAdd('ai_module.obj', opts=OPTS)
-  TargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai'])
+  TargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai', 'IMPORT:panda3d.core'])
 
   TargetAdd('ai.pyd', input='ai_module.obj')
   TargetAdd('ai.pyd', input='libpandaai_igate.obj')
   TargetAdd('ai.pyd', input='libpandaai.dll')
-  TargetAdd('ai.pyd', input='core.pyd')
   TargetAdd('ai.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('ai.pyd', opts=['PYTHON'])
 

+ 1 - 0
makepanda/makepandacore.py

@@ -81,6 +81,7 @@ MAYAVERSIONINFO = [("MAYA6",   "6.0"),
                    ("MAYA20135","2013.5"),
                    ("MAYA2014","2014"),
                    ("MAYA2015","2015"),
+                   ("MAYA2016","2016"),
 ]
 
 MAXVERSIONINFO = [("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0", "installdir", "maxsdk\\cssdk\\include"),

+ 1 - 1
panda/src/bullet/bulletRigidBodyNode.h

@@ -33,7 +33,7 @@ class BulletShape;
 class EXPCL_PANDABULLET BulletRigidBodyNode : public BulletBodyNode {
 
 PUBLISHED:
-  BulletRigidBodyNode(const char *name="rigid");
+  explicit BulletRigidBodyNode(const char *name="rigid");
   INLINE ~BulletRigidBodyNode();
 
   // Mass & inertia

+ 0 - 2
panda/src/chan/animChannelMatrixFixed.h

@@ -20,8 +20,6 @@
 #include "animChannel.h"
 #include "luse.h"
 
-EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_CHAN, EXPTP_PANDA_CHAN, AnimChannel<ACMatrixSwitchType>);
-
 ////////////////////////////////////////////////////////////////////
 //       Class : AnimChannelMatrixFixed
 // Description : A specialization on AnimChannel to add all the

+ 2 - 2
panda/src/dxgsg9/dxGeomMunger9.cxx

@@ -118,7 +118,7 @@ munge_format_impl(const GeomVertexFormat *orig,
 
   if (normal_type != (const GeomVertexColumn *)NULL) {
     new_array_format->add_column
-      (InternalName::get_normal(), 3, NT_float32, C_vector);
+      (InternalName::get_normal(), 3, NT_float32, C_normal);
     new_format->remove_column(normal_type->get_name());
   }
 
@@ -227,7 +227,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
 
   if (normal_type != (const GeomVertexColumn *)NULL) {
     new_array_format->add_column
-      (InternalName::get_normal(), 3, NT_float32, C_vector);
+      (InternalName::get_normal(), 3, NT_float32, C_normal);
     new_format->remove_column(normal_type->get_name());
   }
 

+ 5 - 32
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -2316,8 +2316,6 @@ reset() {
     Geom::GR_triangle_strip | Geom::GR_triangle_fan |
     Geom::GR_flat_first_vertex;
 
-  _auto_rescale_normal = false;
-
   // overwrite gsg defaults with these values
 
   HRESULT hr;
@@ -2864,10 +2862,6 @@ do_issue_transform() {
   }
 
   _transform_stale = false;
-
-  if (_auto_rescale_normal) {
-    do_auto_rescale_normal();
-  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -3001,10 +2995,12 @@ do_issue_render_mode() {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
 do_issue_rescale_normal() {
-  const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot()));
-  RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
+  RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
 
-  _auto_rescale_normal = false;
+  const RescaleNormalAttrib *target_rescale_normal;
+  if (_target_rs->get_attrib(target_rescale_normal)) {
+    mode = target_rescale_normal->get_mode();
+  }
 
   switch (mode) {
   case RescaleNormalAttrib::M_none:
@@ -3016,11 +3012,6 @@ do_issue_rescale_normal() {
     set_render_state(D3DRS_NORMALIZENORMALS, true);
     break;
 
-  case RescaleNormalAttrib::M_auto:
-    _auto_rescale_normal = true;
-    do_auto_rescale_normal();
-    break;
-
   default:
     dxgsg9_cat.error()
       << "Unknown rescale_normal mode " << (int)mode << endl;
@@ -4234,24 +4225,6 @@ set_read_buffer(const RenderBuffer &rb) {
   return;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::do_auto_rescale_normal
-//       Access: Protected
-//  Description: Issues the appropriate DX commands to either rescale
-//               or normalize the normals according to the current
-//               transform.
-////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian9::
-do_auto_rescale_normal() {
-  if (_internal_transform->has_identity_scale()) {
-    // If there's no scale, don't normalize anything.
-    set_render_state(D3DRS_NORMALIZENORMALS, false);
-  } else {
-    // If there is a scale, turn on normalization.
-    set_render_state(D3DRS_NORMALIZENORMALS, true);
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::get_light_color
 //       Access: Public

+ 0 - 3
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -208,8 +208,6 @@ protected:
   void set_draw_buffer(const RenderBuffer &rb);
   void set_read_buffer(const RenderBuffer &rb);
 
-  void do_auto_rescale_normal();
-
   void disable_standard_vertex_arrays();
   bool update_standard_vertex_arrays(bool force);
   void disable_standard_texture_bindings();
@@ -277,7 +275,6 @@ protected:
   bool _supports_render_texture;
 
   RenderBuffer::Type _cur_read_pixel_buffer;  // source for copy_pixel_buffer operation
-  bool _auto_rescale_normal;
 
   PN_stdfloat _material_ambient;
   PN_stdfloat _material_diffuse;

+ 1 - 1
panda/src/egg/eggGroupNode.h

@@ -26,6 +26,7 @@
 #include "luse.h"
 #include "globPattern.h"
 #include "plist.h"
+#include "bamCacheRecord.h"
 
 class EggTextureCollection;
 class EggMaterialCollection;
@@ -33,7 +34,6 @@ class EggPolygon;
 class EggVertex;
 class EggVertexPool;
 class DSearchPath;
-class BamCacheRecord;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : EggGroupNode

+ 1 - 1
panda/src/egg2pg/eggLoader.cxx

@@ -2256,7 +2256,7 @@ make_vertex_data(const EggRenderState *render_state,
   if (vertex_pool->has_normals()) {
     array_format->add_column
       (InternalName::get_normal(), 3,
-       Geom::NT_stdfloat, Geom::C_vector);
+       Geom::NT_stdfloat, Geom::C_normal);
   }
 
   if (!ignore_color) {

+ 66 - 4
panda/src/egg2pg/eggSaver.cxx

@@ -431,7 +431,6 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
   apply_node_properties(egg_group, node, false);
 
   // turn it into a collision node
-  egg_group->set_cs_type(EggGroup::CST_polyset);
   egg_group->set_collide_flags(EggGroup::CF_descend);
 
   NodePath np = node_path.get_node_path();
@@ -451,6 +450,8 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
     for (int i = 0; i < num_solids; i++) {
       CPT(CollisionSolid) child = node->get_solid(i);
       if (child->is_of_type(CollisionPolygon::get_class_type())) {
+        egg_group->set_cs_type(EggGroup::CST_polyset);
+
         EggPolygon *egg_poly = new EggPolygon;
         egg_group->add_child(egg_poly);
 
@@ -464,10 +465,71 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
           EggVertex *new_egg_vert = cvpool->create_unique_vertex(egg_vert);
           egg_poly->add_vertex(new_egg_vert);
         }
-      } else if (child->is_of_type(CollisionPlane::get_class_type())) {
-        nout << "Encountered unhandled collsion type: CollisionPlane" << "\n";
+
       } else if (child->is_of_type(CollisionSphere::get_class_type())) {
-        nout << "Encountered unhandled collsion type: CollisionSphere" << "\n";
+        CPT(CollisionSphere) sphere = DCAST(CollisionSphere, child);
+        LPoint3 center = sphere->get_center();
+        LVector3 offset(sphere->get_radius(), 0, 0);
+
+        EggGroup *egg_sphere;
+        if (num_solids == 1) {
+          egg_sphere = egg_group;
+        } else {
+          egg_sphere = new EggGroup;
+          egg_sphere->set_collide_flags(EggGroup::CF_descend);
+          egg_group->add_child(egg_sphere);
+        }
+        egg_sphere->set_cs_type(EggGroup::CST_sphere);
+
+        EggVertex ev1, ev2;
+        ev1.set_pos(LCAST(double, (center + offset) * net_mat));
+        ev2.set_pos(LCAST(double, (center - offset) * net_mat));
+
+        EggPolygon *egg_poly = new EggPolygon;
+        egg_sphere->add_child(egg_poly);
+
+        egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
+        egg_poly->add_vertex(cvpool->create_unique_vertex(ev2));
+
+      } else if (child->is_of_type(CollisionPlane::get_class_type())) {
+        LPlane plane = DCAST(CollisionPlane, child)->get_plane();
+        LPoint3 origin = plane.get_point();
+        LVector3 normal = plane.get_normal();
+
+        // Get an arbitrary vector on the plane by taking the cross product
+        // with any vector, as long as it is different.
+        LVector3 vec1;
+        if (abs(normal[2]) > abs(normal[1])) {
+          vec1 = normal.cross(LVector3(0, 1, 0));
+        } else {
+          vec1 = normal.cross(LVector3(0, 0, 1));
+        }
+
+        // Find a second vector perpendicular to the two.
+        LVector3 vec2 = normal.cross(vec1);
+
+        EggGroup *egg_plane;
+        if (num_solids == 1) {
+          egg_plane = egg_group;
+        } else {
+          egg_plane = new EggGroup;
+          egg_plane->set_collide_flags(EggGroup::CF_descend);
+          egg_group->add_child(egg_plane);
+        }
+        egg_plane->set_cs_type(EggGroup::CST_plane);
+
+        EggVertex ev0, ev1, ev2;
+        ev0.set_pos(LCAST(double, origin * net_mat));
+        ev1.set_pos(LCAST(double, (origin + vec1) * net_mat));
+        ev2.set_pos(LCAST(double, (origin + vec2) * net_mat));
+
+        EggPolygon *egg_poly = new EggPolygon;
+        egg_plane->add_child(egg_poly);
+
+        egg_poly->add_vertex(cvpool->create_unique_vertex(ev0));
+        egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
+        egg_poly->add_vertex(cvpool->create_unique_vertex(ev2));
+
       } else if (child->is_of_type(CollisionBox::get_class_type())) {
         nout << "Encountered unhandled collsion type: CollisionBox" << "\n";
       } else if (child->is_of_type(CollisionInvSphere::get_class_type())) {

+ 4 - 0
panda/src/express/Sources.pp

@@ -23,7 +23,9 @@
     encrypt_string.h \
     error_utils.h \
     export_dtool.h \
+    filename_ext.h \
     fileReference.h fileReference.I \
+    globPattern_ext.h \
     hashGeneratorBase.I hashGeneratorBase.h \
     hashVal.I hashVal.h \
     indirectLess.I indirectLess.h \
@@ -45,6 +47,7 @@
     patchfile.I patchfile.h \
     pointerTo.I pointerTo.h \
     pointerToArray.I pointerToArray.h \
+    pointerToArray_ext.h \
     pointerToArrayBase.I pointerToArrayBase.h \
     pointerToBase.I pointerToBase.h \
     pointerToVoid.I pointerToVoid.h \
@@ -61,6 +64,7 @@
     threadSafePointerTo.I threadSafePointerTo.h \
     threadSafePointerToBase.I threadSafePointerToBase.h \
     trueClock.I trueClock.h \
+    typeHandle_ext.h \
     typedReferenceCount.I typedReferenceCount.h typedef.h \
     vector_uchar.h vector_double.h vector_float.h \
     vector_stdfloat.h \

+ 3 - 3
panda/src/express/memoryUsagePointers_ext.cxx

@@ -17,9 +17,9 @@
 #if defined(HAVE_PYTHON) && defined(DO_MEMORY_USAGE)
 
 #ifndef CPPPARSER
-extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedObject;
-extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedReferenceCount;
-extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_ReferenceCount;
+extern Dtool_PyTypedObject Dtool_TypedObject;
+extern Dtool_PyTypedObject Dtool_TypedReferenceCount;
+extern Dtool_PyTypedObject Dtool_ReferenceCount;
 #endif  // CPPPARSER
 
 ////////////////////////////////////////////////////////////////////

+ 13 - 0
panda/src/express/namable.I

@@ -45,6 +45,19 @@ operator = (const Namable &other) {
   return *this;
 }
 
+#ifdef USE_MOVE_SEMANTICS
+////////////////////////////////////////////////////////////////////
+//     Function: Namable::Copy Assignment Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Namable &Namable::
+operator = (Namable &&other) NOEXCEPT {
+  _name = MOVE(other._name);
+  return *this;
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Namable::set_name
 //       Access: Public

+ 5 - 1
panda/src/express/namable.h

@@ -28,10 +28,14 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAEXPRESS Namable : public MemoryBase {
 PUBLISHED:
-  INLINE Namable(const string &initial_name = "");
+  INLINE explicit Namable(const string &initial_name = "");
   INLINE Namable(const Namable &copy);
   INLINE Namable &operator = (const Namable &other);
 
+#ifdef USE_MOVE_SEMANTICS
+  INLINE Namable &operator = (Namable &&other) NOEXCEPT;
+#endif
+
   INLINE void set_name(const string &name);
   INLINE void clear_name();
   INLINE bool has_name() const;

+ 4 - 0
panda/src/express/pta_uchar.h

@@ -29,10 +29,14 @@
 //               rather than defining the pta again.
 ////////////////////////////////////////////////////////////////////
 
+#if !defined(__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+// GCC 4.6 has a weird bug related to this type.
+#else
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, PointerToBase<ReferenceCountedVector<uchar> >)
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, PointerToArrayBase<uchar>)
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, PointerToArray<unsigned char>)
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS, ConstPointerToArray<unsigned char>)
+#endif
 
 typedef PointerToArray<unsigned char> PTA_uchar;
 typedef ConstPointerToArray<unsigned char> CPTA_uchar;

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

@@ -2304,8 +2304,6 @@ reset() {
   }
 #endif
 
-  _auto_rescale_normal = false;
-
   // Ensure the initial state is what we say it should be (in some
   // cases, we don't want the GL default settings; in others, we have
   // to force the point with some drivers that aren't strictly
@@ -5956,10 +5954,6 @@ do_issue_transform() {
   DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
   glMatrixMode(GL_MODELVIEW);
   GLPf(LoadMatrix)(transform->get_mat().get_data());
-
-  if (_auto_rescale_normal) {
-    do_auto_rescale_normal();
-  }
 #endif
   _transform_stale = false;
 
@@ -6179,12 +6173,12 @@ do_issue_antialias() {
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 do_issue_rescale_normal() {
-  const RescaleNormalAttrib *target_rescale_normal;
-  _target_rs->get_attrib_def(target_rescale_normal);
-
-  RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
+  RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
 
-  _auto_rescale_normal = false;
+  const RescaleNormalAttrib *target_rescale_normal;
+  if (_target_rs->get_attrib(target_rescale_normal)) {
+    mode = target_rescale_normal->get_mode();
+  }
 
   switch (mode) {
   case RescaleNormalAttrib::M_none:
@@ -6210,11 +6204,6 @@ do_issue_rescale_normal() {
     }
     break;
 
-  case RescaleNormalAttrib::M_auto:
-    _auto_rescale_normal = true;
-    do_auto_rescale_normal();
-    break;
-
   default:
     GLCAT.error()
       << "Unknown rescale_normal mode " << (int)mode << endl;
@@ -9492,61 +9481,6 @@ free_pointers() {
 #endif
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::do_auto_rescale_normal
-//       Access: Protected
-//  Description: Issues the appropriate GL commands to either rescale
-//               or normalize the normals according to the current
-//               transform.
-////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
-do_auto_rescale_normal() {
-#ifndef OPENGLES_2
-  if (_internal_transform->has_identity_scale()) {
-    // If there's no scale at all, don't do anything.
-    glDisable(GL_NORMALIZE);
-    if (GLCAT.is_spam()) {
-      GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
-    }
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glDisable(GL_RESCALE_NORMAL);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
-      }
-    }
-
-  } else if (_internal_transform->has_uniform_scale()) {
-    // There's a uniform scale; use the rescale feature if available.
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glEnable(GL_RESCALE_NORMAL);
-      glDisable(GL_NORMALIZE);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glEnable(GL_RESCALE_NORMAL)\n";
-        GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
-      }
-    } else {
-      glEnable(GL_NORMALIZE);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
-      }
-    }
-
-  } else {
-    // If there's a non-uniform scale, normalize everything.
-    glEnable(GL_NORMALIZE);
-    if (GLCAT.is_spam()) {
-      GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
-    }
-    if (_supports_rescale_normal && support_rescale_normal) {
-      glDisable(GL_RESCALE_NORMAL);
-      if (GLCAT.is_spam()) {
-        GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
-      }
-    }
-  }
-#endif
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::do_issue_texture
 //       Access: Protected, Virtual

+ 0 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -527,7 +527,6 @@ protected:
   void upload_usage_texture(int width, int height);
 #endif  // NDEBUG
 
-  void do_auto_rescale_normal();
   bool specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler);
   bool apply_texture(TextureContext *tc);
   bool apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc);
@@ -627,7 +626,6 @@ protected:
   DirectionalLights _dlights;
 
   int _pass_number;
-  bool _auto_rescale_normal;
   GLuint _geom_display_list;
   GLuint _current_vbuffer_index;
   GLuint _current_ibuffer_index;

+ 3 - 1
panda/src/glstuff/glShaderContext_src.cxx

@@ -589,7 +589,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
   // Strip off [0] suffix that some drivers append to arrays.
   size_t size = strlen(name_buffer);
   if (size > 3 && strncmp(name_buffer + (size - 3), "[0]", 3) == 0) {
-    name_buffer[size - 3] = 0;
+    size -= 3;
+    name_buffer[size] = 0;
   }
 
   string param_name(name_buffer);
@@ -606,6 +607,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
     bool transpose = false;
     bool inverse = false;
     string matrix_name(noprefix);
+    size = matrix_name.size();
 
     // Check for and chop off any "Transpose" or "Inverse" suffix.
     if (size > 15 && matrix_name.compare(size - 9, 9, "Transpose") == 0) {

+ 9 - 2
panda/src/gobj/Sources.pp

@@ -50,9 +50,11 @@
     matrixLens.I matrixLens.h \
     occlusionQueryContext.I occlusionQueryContext.h \
     orthographicLens.I orthographicLens.h perspectiveLens.I  \
+    paramTexture.I paramTexture.h \
     perspectiveLens.h \
     preparedGraphicsObjects.I preparedGraphicsObjects.h \
     queryContext.I queryContext.h \
+    samplerState.I samplerState.h \
     savedContext.I savedContext.h \
     shader.I shader.h \
     shaderContext.h shaderContext.I \
@@ -61,6 +63,7 @@
     sliderTable.I sliderTable.h \
     texture.I texture.h \
     textureCollection.I textureCollection.h \
+    textureCollection_ext.h \
     textureContext.I textureContext.h \
     texturePeeker.I texturePeeker.h \
     texturePool.I texturePool.h \
@@ -123,9 +126,11 @@
     materialPool.cxx matrixLens.cxx \
     occlusionQueryContext.cxx \
     orthographicLens.cxx  \
+    paramTexture.cxx \
     perspectiveLens.cxx \
     preparedGraphicsObjects.cxx \
     queryContext.cxx \
+    samplerState.cxx \
     savedContext.cxx \
     shader.cxx \
     shaderContext.cxx \
@@ -196,10 +201,12 @@
     material.I material.h \
     materialPool.I materialPool.h matrixLens.I matrixLens.h \
     occlusionQueryContext.I occlusionQueryContext.h \
-    orthographicLens.I orthographicLens.h perspectiveLens.I \
-    perspectiveLens.h \
+    orthographicLens.I orthographicLens.h \
+    paramTexture.I paramTexture.h \
+    perspectiveLens.I perspectiveLens.h \
     preparedGraphicsObjects.I preparedGraphicsObjects.h \
     queryContext.I queryContext.h \
+    samplerState.I samplerState.h \
     savedContext.I savedContext.h \
     shader.I shader.h \
     shaderContext.h shaderContext.I \

+ 1 - 1
panda/src/gobj/geom.h

@@ -60,7 +60,7 @@ protected:
   virtual PT(CopyOnWriteObject) make_cow_copy();
 
 PUBLISHED:
-  Geom(const GeomVertexData *data);
+  explicit Geom(const GeomVertexData *data);
 
 protected:
   Geom(const Geom &copy);

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

@@ -151,6 +151,9 @@ operator << (ostream &out, GeomEnums::Contents contents) {
 
   case GeomEnums::C_matrix:
     return out << "matrix";
+
+  case GeomEnums::C_normal:
+    return out << "normal";
   }
 
   return out << "**invalid contents (" << (int)contents << ")**";

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

@@ -196,7 +196,7 @@ PUBLISHED:
     C_other,        // Arbitrary meaning, leave it alone
     C_point,        // A point in 3-space or 4-space
     C_clip_point,   // A point pre-transformed into clip coordinates
-    C_vector,       // A surface normal, tangent, or binormal
+    C_vector,       // A surface tangent or binormal (see C_normal for normals)
     C_texcoord,     // A texture coordinate
     C_color,        // 3- or 4-component color, ordered R, G, B, [A]
     C_index,        // An index value into some other table
@@ -205,6 +205,10 @@ PUBLISHED:
     // A transformation matrix.  This is typically three or four
     // columns, but we pretend it's only one for convenience.
     C_matrix,
+
+    // A special version of C_vector that should be used for normal
+    // vectors, which are scaled differently from other vectors.
+    C_normal,
   };
 
   // The type of animation data that is represented by a particular

+ 2 - 2
panda/src/gobj/geomVertexArrayData.h

@@ -68,8 +68,8 @@ protected:
   virtual PT(CopyOnWriteObject) make_cow_copy();
 
 PUBLISHED:
-  GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
-                      UsageHint usage_hint);
+  explicit GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
+                               UsageHint usage_hint);
   GeomVertexArrayData(const GeomVertexArrayData &copy);
   void operator = (const GeomVertexArrayData &copy);
   virtual ~GeomVertexArrayData();

+ 5 - 2
panda/src/gobj/geomVertexArrayFormat.cxx

@@ -394,8 +394,11 @@ align_columns_for_animation() {
   Columns::const_iterator ci;
   for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) {
     GeomVertexColumn *column = (*ci);
-    if ((column->get_contents() == C_point || column->get_contents() == C_vector) &&
-        (column->get_numeric_type() == NT_float32 || column->get_numeric_type() == NT_float64) &&
+    if ((column->get_contents() == C_point ||
+         column->get_contents() == C_vector ||
+         column->get_contents() == C_normal) &&
+        (column->get_numeric_type() == NT_float32 ||
+         column->get_numeric_type() == NT_float64) &&
         column->get_num_components() >= 3) {
       add_column(column->get_name(), 4, column->get_numeric_type(), column->get_contents(), -1, 16);
     } else {

+ 6 - 0
panda/src/gobj/geomVertexColumn.cxx

@@ -352,6 +352,12 @@ make_packer() const {
     }
     return new Packer_color;
 
+  case C_normal:
+    if (get_num_values() != 3 && get_num_values() != 4) {
+      gobj_cat.error()
+        << "GeomVertexColumn with contents C_normal must have 3 or 4 components!\n";
+    }
+
   default:
     // Otherwise, we just read it as a generic value.
     switch (get_numeric_type()) {

+ 64 - 7
panda/src/gobj/geomVertexData.cxx

@@ -1915,10 +1915,37 @@ do_transform_point_column(const GeomVertexFormat *format, GeomVertexRewriter &da
 ////////////////////////////////////////////////////////////////////
 void GeomVertexData::
 do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
-                          const LMatrix4 &mat, int begin_row, int end_row) {
+                           const LMatrix4 &mat, int begin_row, int end_row) {
   const GeomVertexColumn *data_column = data.get_column();
   int num_values = data_column->get_num_values();
 
+  LMatrix4 xform;
+  bool normalize = false;
+  if (data_column->get_contents() == C_normal) {
+    // This is to preserve perpendicularity to the surface.
+    LVecBase3 scale, shear, hpr;
+    if (decompose_matrix(mat.get_upper_3(), scale, shear, hpr) &&
+        IS_NEARLY_EQUAL(scale[0], scale[1]) &&
+        IS_NEARLY_EQUAL(scale[0], scale[2])) {
+      if (scale[0] == 1) {
+        // No scale to worry about.
+        xform = mat;
+      } else {
+        // Simply take the uniform scale out of the transformation.
+        // Not sure if it might be better to just normalize?
+        compose_matrix(xform, LVecBase3(1, 1, 1), shear, hpr, LVecBase3::zero());
+      }
+    } else {
+      // There is a non-uniform scale, so we need to do all this to
+      // preserve orthogonality to the surface.
+      xform.invert_from(mat);
+      xform.transpose_in_place();
+      normalize = true;
+    }
+  } else {
+    xform = mat;
+  }
+
   if ((num_values == 3 || num_values == 4) &&
       data_column->get_numeric_type() == NT_float32) {
     // The table of vectors is a table of LVector3f's or LVector4f's.
@@ -1929,9 +1956,11 @@ do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &d
     size_t num_rows = end_row - begin_row;
     unsigned char *datat = data_handle->get_write_pointer();
     datat += data_column->get_start() + begin_row * stride;
-    LMatrix4f matf = LCAST(float, mat);
+    LMatrix4f matf = LCAST(float, xform);
 
-    if (num_values == 3) {
+    if (normalize) {
+      table_xform_normal3f(datat, num_rows, stride, matf);
+    } else if (num_values == 3) {
       table_xform_vector3f(datat, num_rows, stride, matf);
     } else {
       table_xform_vecbase4f(datat, num_rows, stride, matf);
@@ -1939,11 +1968,20 @@ do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &d
 
   } else {
     // Use the GeomVertexRewriter to transform the vectors.
-
     data.set_row_unsafe(begin_row);
-    for (int j = begin_row; j < end_row; ++j) {
-      LVector3 vertex = data.get_data3();
-      data.set_data3(vertex * mat);
+
+    if (normalize) {
+      for (int j = begin_row; j < end_row; ++j) {
+        LVector3 vector = data.get_data3();
+        vector *= xform;
+        vector.normalize();
+        data.set_data3(vector);
+      }
+    } else {
+      for (int j = begin_row; j < end_row; ++j) {
+        LVector3 vector = data.get_data3();
+        data.set_data3(vector * xform);
+      }
     }
   }
 }
@@ -1965,6 +2003,25 @@ table_xform_point3f(unsigned char *datat, size_t num_rows, size_t stride,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexData::table_xform_normal3f
+//       Access: Private, Static
+//  Description: Transforms each of the LVector3f objects in the
+//               indicated table by the indicated matrix, and also
+//               normalizes them.
+////////////////////////////////////////////////////////////////////
+void GeomVertexData::
+table_xform_normal3f(unsigned char *datat, size_t num_rows, size_t stride,
+                     const LMatrix4f &matf) {
+  // We don't bother checking for the unaligned case here, because in
+  // practice it doesn't matter with a 3-component vector.
+  for (size_t i = 0; i < num_rows; ++i) {
+    LNormalf &vertex = *(LNormalf *)(&datat[i * stride]);
+    vertex *= matf;
+    vertex.normalize();
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexData::table_xform_vector3f
 //       Access: Private, Static

+ 7 - 5
panda/src/gobj/geomVertexData.h

@@ -80,12 +80,12 @@ protected:
   virtual PT(CopyOnWriteObject) make_cow_copy();
 
 PUBLISHED:
-  GeomVertexData(const string &name,
-                 const GeomVertexFormat *format,
-                 UsageHint usage_hint);
+  explicit GeomVertexData(const string &name,
+                          const GeomVertexFormat *format,
+                          UsageHint usage_hint);
   GeomVertexData(const GeomVertexData &copy);
-  GeomVertexData(const GeomVertexData &copy,
-                 const GeomVertexFormat *format);
+  explicit GeomVertexData(const GeomVertexData &copy,
+                          const GeomVertexFormat *format);
   void operator = (const GeomVertexData &copy);
   virtual ~GeomVertexData();
   ALLOC_DELETED_CHAIN(GeomVertexData);
@@ -339,6 +339,8 @@ private:
                                   const LMatrix4 &mat, int begin_row, int end_row);
   static void table_xform_point3f(unsigned char *datat, size_t num_rows,
                                   size_t stride, const LMatrix4f &matf);
+  static void table_xform_normal3f(unsigned char *datat, size_t num_rows,
+                                   size_t stride, const LMatrix4f &matf);
   static void table_xform_vector3f(unsigned char *datat, size_t num_rows,
                                    size_t stride, const LMatrix4f &matf);
   static void table_xform_vecbase4f(unsigned char *datat, size_t num_rows,

+ 7 - 6
panda/src/gobj/geomVertexFormat.cxx

@@ -825,6 +825,7 @@ do_register() {
       break;
 
     case C_vector:
+    case C_normal:
       // It's a vector.
       _vectors.push_back(column->get_name());
       break;
@@ -1017,7 +1018,7 @@ make_standard_formats() {
                           (InternalName::get_vertex(), 3,
                            NT_stdfloat, C_point,
                            InternalName::get_normal(), 3,
-                           NT_stdfloat, C_vector));
+                           NT_stdfloat, C_normal));
 
   _v3t2 = register_format(new GeomVertexArrayFormat
                           (InternalName::get_vertex(), 3,
@@ -1029,7 +1030,7 @@ make_standard_formats() {
                             (InternalName::get_vertex(), 3,
                              NT_stdfloat, C_point,
                              InternalName::get_normal(), 3,
-                             NT_stdfloat, C_vector,
+                             NT_stdfloat, C_normal,
                              InternalName::get_texcoord(), 2,
                              NT_stdfloat, C_texcoord));
 
@@ -1044,7 +1045,7 @@ make_standard_formats() {
                             (InternalName::get_vertex(), 3,
                              NT_stdfloat, C_point,
                              InternalName::get_normal(), 3,
-                             NT_stdfloat, C_vector,
+                             NT_stdfloat, C_normal,
                              InternalName::get_color(), 1,
                              NT_packed_dabc, C_color));
 
@@ -1060,7 +1061,7 @@ make_standard_formats() {
                               (InternalName::get_vertex(), 3,
                                NT_stdfloat, C_point,
                                InternalName::get_normal(), 3,
-                               NT_stdfloat, C_vector,
+                               NT_stdfloat, C_normal,
                                InternalName::get_color(), 1,
                                NT_packed_dabc, C_color,
                                InternalName::get_texcoord(), 2,
@@ -1079,7 +1080,7 @@ make_standard_formats() {
                             (InternalName::get_vertex(), 3,
                              NT_stdfloat, C_point,
                              InternalName::get_normal(), 3,
-                             NT_stdfloat, C_vector,
+                             NT_stdfloat, C_normal,
                              InternalName::get_color(), 4,
                              NT_uint8, C_color));
 
@@ -1095,7 +1096,7 @@ make_standard_formats() {
                               (InternalName::get_vertex(), 3,
                                NT_stdfloat, C_point,
                                InternalName::get_normal(), 3,
-                               NT_stdfloat, C_vector,
+                               NT_stdfloat, C_normal,
                                InternalName::get_color(), 4,
                                NT_uint8, C_color,
                                InternalName::get_texcoord(), 2,

+ 11 - 5
panda/src/gobj/perspectiveLens.cxx

@@ -82,12 +82,18 @@ do_compute_projection_mat(Lens::CData *lens_cdata) {
   PN_stdfloat fl = do_get_focal_length(lens_cdata);
   PN_stdfloat fFar = do_get_far(lens_cdata);
   PN_stdfloat fNear = do_get_near(lens_cdata);
-  PN_stdfloat far_minus_near = fFar-fNear;
-  PN_stdfloat a = (fFar + fNear);
-  PN_stdfloat b = -2.0f * fFar * fNear;
+  PN_stdfloat a, b;
 
-  a /= far_minus_near;
-  b /= far_minus_near;
+  if (cinf(fFar)) {
+    a = 1;
+    b = -2 * fNear;
+  } else {
+    PN_stdfloat far_minus_near = fFar-fNear;
+    a = (fFar + fNear);
+    b = -2 * fFar * fNear;
+    a /= far_minus_near;
+    b /= far_minus_near;
+  }
 
   LMatrix4 canonical;
   switch (cs) {

+ 12 - 6
panda/src/gobj/texture.cxx

@@ -2892,6 +2892,8 @@ do_read_one(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpa
   }
   image.copy_header_from(*image_reader);
 
+  AutoTextureScale auto_texture_scale = do_get_auto_texture_scale(cdata);
+
   // If it's a floating-point image file, read it by default into a
   // floating-point texture.
   bool read_floating_point;
@@ -2929,9 +2931,7 @@ do_read_one(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpa
       y_size = 1;
 
     } else {
-      consider_rescale(image, fullpath.get_basename(), do_get_auto_texture_scale(cdata));
-      x_size = image.get_read_x_size();
-      y_size = image.get_read_y_size();
+      adjust_size(x_size, y_size, fullpath.get_basename(), false, auto_texture_scale);
     }
 
     if (read_floating_point) {
@@ -2949,9 +2949,15 @@ do_read_one(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpa
 
   } else {
     if (z == 0 && n == 0) {
-      cdata->_orig_file_x_size = image.get_x_size();
-      cdata->_orig_file_y_size = image.get_y_size();
-      consider_rescale(image, fullpath.get_basename(), do_get_auto_texture_scale(cdata));
+      int x_size = image.get_x_size();
+      int y_size = image.get_y_size();
+
+      cdata->_orig_file_x_size = x_size;
+      cdata->_orig_file_y_size = y_size;
+
+      if (adjust_size(x_size, y_size, fullpath.get_basename(), false, auto_texture_scale)) {
+        image.set_read_size(x_size, y_size);
+      }
     } else {
       image.set_read_size(do_get_expected_mipmap_x_size(cdata, n),
                           do_get_expected_mipmap_y_size(cdata, n));

+ 1 - 1
panda/src/gobj/texture.h

@@ -43,6 +43,7 @@
 #include "pnmImage.h"
 #include "colorSpace.h"
 #include "geomEnums.h"
+#include "bamCacheRecord.h"
 
 class PNMImage;
 class PfmFile;
@@ -51,7 +52,6 @@ class FactoryParams;
 class PreparedGraphicsObjects;
 class CullTraverser;
 class CullTraverserData;
-class BamCacheRecord;
 class TexturePeeker;
 struct DDSHeader;
 

+ 1 - 1
panda/src/gobj/textureStage.h

@@ -37,7 +37,7 @@ class FactoryParams;
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA_GOBJ TextureStage : public TypedWritableReferenceCount {
 PUBLISHED:
-  TextureStage(const string &name);
+  explicit TextureStage(const string &name);
   INLINE TextureStage(TextureStage &copy);
   void operator = (const TextureStage &copy);
 

+ 3 - 0
panda/src/grutil/geoMipTerrain.I

@@ -385,8 +385,11 @@ get_flatten_mode() {
 ////////////////////////////////////////////////////////////////////
 INLINE const NodePath GeoMipTerrain::
 get_block_node_path(unsigned short mx, unsigned short my) {
+  nassertr(mx < _blocks.size(), NodePath::fail());
+  nassertr(my < _blocks[mx].size(), NodePath::fail());
   return _blocks[mx][my];
 }
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeoMipTerrain::get_block_from_pos
 //       Access: Published

+ 1 - 1
panda/src/grutil/geoMipTerrain.cxx

@@ -63,7 +63,7 @@ generate_block(unsigned short mx,
   array->add_column(InternalName::get_texcoord(), 2,
                     Geom::NT_stdfloat, Geom::C_texcoord);
   array->add_column(InternalName::get_normal(), 3,
-                    Geom::NT_stdfloat, Geom::C_vector);
+                    Geom::NT_stdfloat, Geom::C_normal);
 
   PT(GeomVertexFormat) format = new GeomVertexFormat();
   format->add_array(array);

+ 2 - 2
panda/src/grutil/pfmVizzer.cxx

@@ -1062,7 +1062,7 @@ make_array_format(const VisColumns &vis_columns) const {
     case CT_normal3:
       num_components = 3;
       numeric_type = GeomEnums::NT_float32;
-      contents = GeomEnums::C_vector;
+      contents = GeomEnums::C_normal;
       break;
 
     case CT_blend1:
@@ -1072,7 +1072,7 @@ make_array_format(const VisColumns &vis_columns) const {
       break;
     }
     nassertr(num_components != 0, NULL);
-    
+
     array_format->add_column(name, num_components, numeric_type, contents);
   }
 

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff