Browse Source

Merge branch 'release/1.10.x'

rdb 5 years ago
parent
commit
30d9f88f8e

+ 1 - 0
direct/src/dist/commands.py

@@ -270,6 +270,7 @@ class build_apps(setuptools.Command):
             'libbz2.so.*', 'libz.so.*', 'liblzma.so.*', 'librt.so.*', 'libutil.so.*',
 
             # macOS
+            '/usr/lib/libc++.1.dylib',
             '/usr/lib/libstdc++.*.dylib',
             '/usr/lib/libz.*.dylib',
             '/usr/lib/libobjc.*.dylib',

+ 2 - 2
direct/src/showbase/Audio3DManager.py

@@ -35,7 +35,7 @@ class Audio3DManager:
     def setDistanceFactor(self, factor):
         """
         Control the scale that sets the distance units for 3D spacialized audio.
-        Default is 1.0 which is adjust in panda to be feet.
+        Default is 1.0 which is adjust in panda to be meters.
         When you change this, don't forget that this effects the scale of setSoundMinDistance
         """
         self.audio_manager.audio3dSetDistanceFactor(factor)
@@ -43,7 +43,7 @@ class Audio3DManager:
     def getDistanceFactor(self):
         """
         Control the scale that sets the distance units for 3D spacialized audio.
-        Default is 1.0 which is adjust in panda to be feet.
+        Default is 1.0 which is adjust in panda to be meters.
         """
         return self.audio_manager.audio3dGetDistanceFactor()
 

+ 30 - 7
direct/src/showbase/ShowBase.py

@@ -1,6 +1,33 @@
 """ This module contains ShowBase, an application framework responsible
 for opening a graphical display, setting up input devices and creating
-the scene graph. """
+the scene graph.
+
+The simplest way to open a ShowBase instance is to execute this code:
+
+.. code-block:: python
+
+   from direct.showbase.ShowBase import ShowBase
+
+   base = ShowBase()
+   base.run()
+
+A common approach is to create your own subclass inheriting from ShowBase.
+
+Built-in global variables
+-------------------------
+
+Some key variables used in all Panda3D scripts are actually attributes of the
+ShowBase instance.  When creating an instance of this class, it will write many
+of these variables to the built-in scope of the Python interpreter, so that
+they are accessible to any Python module.
+
+While these are handy for prototyping, we do not recommend using them in bigger
+projects, as it can make the code confusing to read to other Python developers,
+to whom it may not be obvious where these variables are originating.
+
+Some of these built-in variables are documented further in the
+:mod:`~direct.showbase.ShowBaseGlobal` module.
+"""
 
 __all__ = ['ShowBase', 'WindowControls']
 
@@ -1109,8 +1136,8 @@ class ShowBase(DirectObject.DirectObject):
         2-d objects and gui elements that are superimposed over the
         3-d geometry in the window.
         """
-        # We've already created aspect2d in ShowBaseGlobal, for the
-        # benefit of creating DirectGui elements before ShowBase.
+        # We've already created render2d and aspect2d in ShowBaseGlobal,
+        # for the benefit of creating DirectGui elements before ShowBase.
         from . import ShowBaseGlobal
 
         ## This is the root of the 2-D scene graph.
@@ -1134,10 +1161,6 @@ class ShowBase(DirectObject.DirectObject):
         self.render2d.setMaterialOff(1)
         self.render2d.setTwoSided(1)
 
-        # We've already created aspect2d in ShowBaseGlobal, for the
-        # benefit of creating DirectGui elements before ShowBase.
-        from . import ShowBaseGlobal
-
         ## The normal 2-d DisplayRegion has an aspect ratio that
         ## matches the window, but its coordinate system is square.
         ## This means anything we parent to render2d gets stretched.

+ 24 - 2
direct/src/showbase/ShowBaseGlobal.py

@@ -17,17 +17,39 @@ from . import DConfig as config
 
 __dev__ = config.GetBool('want-dev', __debug__)
 
-#: The global instance of the :class:`panda3d.core.VirtualFileSystem`.
+#: The global instance of the :class:`~panda3d.core.VirtualFileSystem`, as
+#: obtained using :meth:`panda3d.core.VirtualFileSystem.getGlobalPtr()`.
 vfs = VirtualFileSystem.getGlobalPtr()
+
+#: The default Panda3D output stream for notifications and logging, as
+#: obtained using :meth:`panda3d.core.Notify.out()`.
 ostream = Notify.out()
+
+#: The clock object used by default for rendering and animation, obtained using
+#: :meth:`panda3d.core.ClockObject.getGlobalClock()`.
 globalClock = ClockObject.getGlobalClock()
+
+#: See :meth:`panda3d.core.ConfigPageManager.getGlobalPtr()`.
 cpMgr = ConfigPageManager.getGlobalPtr()
+
+#: See :meth:`panda3d.core.ConfigVariableManager.getGlobalPtr()`.
 cvMgr = ConfigVariableManager.getGlobalPtr()
+
+#: See :meth:`panda3d.core.PandaSystem.getGlobalPtr()`.
 pandaSystem = PandaSystem.getGlobalPtr()
 
-# This is defined here so GUI elements can be instantiated before ShowBase.
+#: The root of the 2-D scene graph.  The coordinate system of this node runs
+#: from -1 to 1, with the X axis running from left to right and the Z axis from
+#: bottom to top.
 render2d = NodePath("render2d")
+
+#: The root of the 2-D scene graph used for GUI rendering.  Unlike render2d,
+#: which may result in elements being stretched in windows that do not have a
+#: square aspect ratio, this node is scaled automatically to ensure that nodes
+#: parented to it do not appear stretched.
 aspect2d = render2d.attachNewNode(PGTop("aspect2d"))
+
+#: A dummy scene graph that is not being rendered by anything.
 hidden = NodePath("hidden")
 
 # Set direct notify categories now that we have config

+ 6 - 0
makepanda/makewheel.py

@@ -407,6 +407,7 @@ class WheelFile(object):
                     deps_path = '@executable_path/../Frameworks'
                 else:
                     deps_path = '@loader_path'
+                remove_signature = False
                 loader_path = [os.path.dirname(source_path)]
                 for dep in deps:
                     if dep.endswith('/Python'):
@@ -439,6 +440,11 @@ class WheelFile(object):
                         continue
 
                     subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
+                    remove_signature = True
+
+                # Remove the codesign signature if we modified the library.
+                if remove_signature:
+                    subprocess.call(["codesign", "--remove-signature", temp.name])
             else:
                 # On other unixes, we just add dependencies normally.
                 for dep in deps:

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

@@ -1075,7 +1075,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
       _target_rs->get_attrib_def(FogAttrib::get_class_slot());
     Fog *fog = target_fog->get_fog();
     if (fog == nullptr) {
-      into[0] = LMatrix4::ones_mat();
+      into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1);
       return;
     }
     PN_stdfloat start, end;

+ 1 - 0
panda/src/express/datagram.h

@@ -97,6 +97,7 @@ public:
 PUBLISHED:
   EXTENSION(INLINE PyObject *get_message() const);
   EXTENSION(INLINE PyObject *__bytes__() const);
+  EXTENSION(PyObject *__reduce__() const);
 
   INLINE size_t get_length() const;
 

+ 26 - 0
panda/src/express/datagram_ext.I

@@ -33,3 +33,29 @@ PyObject *Extension<Datagram>::
 __bytes__() const {
   return get_message();
 }
+
+/**
+ * This special Python method is implemented to provide support for the pickle
+ * module.
+ */
+INLINE PyObject *Extension<Datagram>::
+__reduce__() const {
+  // We should return at least a 2-tuple, (Class, (args)): the necessary class
+  // object whose constructor we should call (e.g.  this), and the arguments
+  // necessary to reconstruct this object.
+  PyObject *args;
+  if (_this->get_length() > 0) {
+    args = PyTuple_New(1);
+    PyTuple_SET_ITEM(args, 0, get_message());
+  } else {
+    args = PyTuple_New(0);
+  }
+
+  extern struct Dtool_PyTypedObject Dtool_Datagram;
+  Py_INCREF((PyObject *)&Dtool_Datagram._PyType);
+
+  PyObject *result = PyTuple_New(2);
+  PyTuple_SET_ITEM(result, 0, (PyObject *)&Dtool_Datagram._PyType);
+  PyTuple_SET_ITEM(result, 1, args);
+  return result;
+}

+ 1 - 0
panda/src/express/datagram_ext.h

@@ -31,6 +31,7 @@ class Extension<Datagram> : public ExtensionBase<Datagram> {
 public:
   INLINE PyObject *get_message() const;
   INLINE PyObject *__bytes__() const;
+  INLINE PyObject *__reduce__() const;
 };
 
 #include "datagram_ext.I"

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

@@ -8489,6 +8489,10 @@ make_shadow_buffer(LightLensNode *light, Texture *tex, GraphicsOutput *host) {
     flags |= GraphicsPipe::BF_size_square;
   }
 
+  if (host != nullptr) {
+    host = host->get_host();
+  }
+
   CLP(GraphicsBuffer) *sbuffer = new CLP(GraphicsBuffer)(get_engine(), get_pipe(), light->get_name(), fbp, props, flags, this, host);
   sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
   get_engine()->add_window(sbuffer, light->get_shadow_buffer_sort());

+ 1 - 1
panda/src/pgraph/geomTransformer.cxx

@@ -1338,7 +1338,7 @@ append_vdata(const GeomVertexData *vdata, int vertex_offset) {
     // The TransformBlendTable.  This one is the easiest, because we can
     // modify it directly, and it will uniquify blend objects for us.
 
-    // We have few special optimizations to handle the TransformBlendTable,
+    // We have a few special optimizations to handle the TransformBlendTable,
     // since it's a very common case and therefore worth spending a bit of
     // effort to optimize deeply.
 

+ 4 - 4
panda/src/tform/mouseWatcher.cxx

@@ -742,7 +742,6 @@ clear_current_regions() {
   }
 }
 
-#ifndef NDEBUG
 /**
  * The protected implementation of show_regions().  This assumes the lock is
  * already held.
@@ -750,6 +749,7 @@ clear_current_regions() {
 void MouseWatcher::
 do_show_regions(const NodePath &render2d, const string &bin_name,
                 int draw_order) {
+#ifndef NDEBUG
   MouseWatcherBase::do_show_regions(render2d, bin_name, draw_order);
   _show_regions_render2d = render2d;
   _show_regions_bin_name = bin_name;
@@ -758,16 +758,16 @@ do_show_regions(const NodePath &render2d, const string &bin_name,
   for (MouseWatcherGroup *group : _groups) {
     group->show_regions(render2d, bin_name, draw_order);
   }
-}
 #endif  // NDEBUG
+}
 
-#ifndef NDEBUG
 /**
  * The protected implementation of hide_regions().  This assumes the lock is
  * already held.
  */
 void MouseWatcher::
 do_hide_regions() {
+#ifndef NDEBUG
   MouseWatcherBase::do_hide_regions();
   _show_regions_render2d = NodePath();
   _show_regions_bin_name = string();
@@ -776,8 +776,8 @@ do_hide_regions() {
   for (MouseWatcherGroup *group : _groups) {
     group->hide_regions();
   }
-}
 #endif  // NDEBUG
+}
 
 /**
  * Computes the list of regions that are in both regions_a and regions_b, as

+ 0 - 4
panda/src/tform/mouseWatcher.h

@@ -157,11 +157,9 @@ protected:
   void set_current_regions(Regions &regions);
   void clear_current_regions();
 
-#ifndef NDEBUG
   virtual void do_show_regions(const NodePath &render2d,
                                const std::string &bin_name, int draw_order);
   virtual void do_hide_regions();
-#endif  // NDEBUG
 
   static void intersect_regions(Regions &only_a,
                                 Regions &only_b,
@@ -260,11 +258,9 @@ private:
   };
   InactivityState _inactivity_state;
 
-#ifndef NDEBUG
   NodePath _show_regions_render2d;
   std::string _show_regions_bin_name;
   int _show_regions_draw_order;
-#endif
 
 protected:
   // Inherited from DataNode

+ 4 - 0
pandatool/src/deploy-stub/deploy-stub.c

@@ -522,6 +522,10 @@ int Py_FrozenMain(int argc, char **argv)
     // for ConfigPageManager to read out and assign to MAIN_DIR.
     sprintf(buffer, "%s/../Resources", dir);
     set_main_dir(buffer);
+
+    // Finally, chdir to it, so that regular Python files are read from the
+    // right location.
+    chdir(buffer);
 #endif
 
     n = PyImport_ImportFrozenModule("__main__");

+ 10 - 0
tests/putil/test_datagram.py

@@ -101,6 +101,16 @@ def test_datagram_get_message():
     assert dg.get_message() == b'abc\x00\xff123'
 
 
+def test_datagram_pickle():
+    import pickle
+
+    dg = core.Datagram()
+    assert pickle.loads(pickle.dumps(dg, -1)) == dg
+
+    dg = core.Datagram(b'abc\x00')
+    assert pickle.loads(pickle.dumps(dg, -1)) == dg
+
+
 def test_iterator(datagram_small):
     """This tests Datagram/DatagramIterator, and sort of serves as a self-check
     of the test fixtures too."""