diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index a4f3bde4fb..10e80e4f08 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -1187,6 +1187,18 @@ class Freezer: else: self.__loadModule(self.ModuleDef(modname, implicit = True)) + # Special case for sysconfig, which depends on a platform-specific + # sysconfigdata module on POSIX systems. + if 'sysconfig' in self.mf.modules: + if sys.version_info >= (3, 6): + if 'linux' in self.platform: + arch = self.platform.split('_', 1)[1] + self.__loadModule(self.ModuleDef('_sysconfigdata__linux_' + arch + '-linux-gnu', implicit=True)) + elif 'mac' in self.platform: + self.__loadModule(self.ModuleDef('_sysconfigdata__darwin_darwin', implicit=True)) + elif 'linux' in self.platform or 'mac' in self.platform: + self.__loadModule(self.ModuleDef('_sysconfigdata', implicit=True)) + # Now, any new modules we found get added to the export list. for origName in list(self.mf.modules.keys()): if origName not in origToNewName: diff --git a/direct/src/showbase/DirectObject.py b/direct/src/showbase/DirectObject.py index f511e8f49d..f97eb76d3c 100644 --- a/direct/src/showbase/DirectObject.py +++ b/direct/src/showbase/DirectObject.py @@ -44,14 +44,14 @@ class DirectObject: def addTask(self, *args, **kwargs): if not hasattr(self, "_taskList"): self._taskList = {} - kwargs['owner']=self + kwargs['owner'] = self task = taskMgr.add(*args, **kwargs) return task def doMethodLater(self, *args, **kwargs): if not hasattr(self, "_taskList"): self._taskList = {} - kwargs['owner']=self + kwargs['owner'] = self task = taskMgr.doMethodLater(*args, **kwargs) return task diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 2ebfd8efe7..b4049a06df 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -800,6 +800,21 @@ if __debug__: whl.write_file(target_path, source_path) + # Include the special sysconfigdata module. + if os.name == 'posix': + import sysconfig + + if hasattr(sysconfig, '_get_sysconfigdata_name'): + modname = sysconfig._get_sysconfigdata_name() + '.py' + else: + modname = '_sysconfigdata.py' + + for entry in sys.path: + source_path = os.path.join(entry, modname) + if os.path.isfile(source_path): + whl.write_file('deploy_libs/' + modname, source_path) + break + # Add plug-ins. for lib in PLUGIN_LIBS: plugin_name = 'lib' + lib diff --git a/panda/src/bullet/bulletConvexHullShape.cxx b/panda/src/bullet/bulletConvexHullShape.cxx index b61722e773..89ec5b2034 100644 --- a/panda/src/bullet/bulletConvexHullShape.cxx +++ b/panda/src/bullet/bulletConvexHullShape.cxx @@ -194,7 +194,7 @@ make_from_bam(const FactoryParams ¶ms) { void BulletConvexHullShape:: fillin(DatagramIterator &scan, BamReader *manager) { BulletShape::fillin(scan, manager); - nassertv(_shape == nullptr); + nassertv(_shape); _shape->setMargin(scan.get_stdfloat()); unsigned int num_points = scan.get_uint32(); diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index a75aec5170..6d4a58adc5 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -21,6 +21,12 @@ #include +static ConfigVariableInt egl_device_index +("egl-device-index", -1, + PRC_DESC("Selects which EGL device index is used to create the EGL display in " + "a headless configuration. The special value -1 selects the default " + "device.")); + TypeHandle eglGraphicsPipe::_type_handle; /** @@ -30,6 +36,8 @@ eglGraphicsPipe:: eglGraphicsPipe() { // Check for client extensions. vector_string extensions; + bool supports_platform_device = false; + bool supports_device_enumeration = false; const char *ext_ptr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); if (ext_ptr != nullptr) { extract_words(ext_ptr, extensions); @@ -42,6 +50,13 @@ eglGraphicsPipe() { out << " " << extension << "\n"; } } + + if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end()) { + supports_platform_device = true; + } + if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) { + supports_device_enumeration = true; + } } else if (egldisplay_cat.is_debug()) { eglGetError(); @@ -51,23 +66,10 @@ eglGraphicsPipe() { EGLint major, minor; - //NB. if the X11 display failed to open, _display will be 0, which is a valid - // input to eglGetDisplay - it means to open the default display. -#ifdef USE_X11 - _egl_display = eglGetDisplay((NativeDisplayType) _display); -#else - _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); -#endif - if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { - egldisplay_cat.warning() - << "Couldn't initialize the default EGL display: " - << get_egl_error_string(eglGetError()) << "\n"; - _egl_display = EGL_NO_DISPLAY; - } - - if (!_egl_display && - std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end() && - std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) { + int index = egl_device_index.get_value(); + if (index >= 0 && supports_platform_device && supports_device_enumeration) { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); @@ -79,23 +81,74 @@ eglGraphicsPipe() { EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices); eglQueryDevicesEXT(num_devices, devices, &num_devices); - if (egldisplay_cat.is_debug()) { - egldisplay_cat.debug() - << "Found " << num_devices << " EGL devices.\n"; + if (index >= num_devices) { + egldisplay_cat.error() + << "Requested EGL device index " << index << " does not exist (" + << "there are only " << num_devices << " devices)\n"; + _is_valid = false; + return; } - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = - (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (egldisplay_cat.is_debug()) { + egldisplay_cat.debug() + << "Found " << num_devices << " EGL devices, using device index " + << index << ".\n"; + } - if (eglGetPlatformDisplayEXT != nullptr) { - for (EGLint i = 0; i < num_devices && !_egl_display; ++i) { - _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr); + _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[index], nullptr); - if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { - egldisplay_cat.warning() - << "Couldn't initialize EGL platform display " << i << ": " - << get_egl_error_string(eglGetError()) << "\n"; - _egl_display = EGL_NO_DISPLAY; + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.error() + << "Couldn't initialize EGL platform display " << index << ": " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } + } + } + else { + //NB. if the X11 display failed to open, _display will be 0, which is a valid + // input to eglGetDisplay - it means to open the default display. + #ifdef USE_X11 + _egl_display = eglGetDisplay((NativeDisplayType) _display); + #else + _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + #endif + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.warning() + << "Couldn't initialize the default EGL display: " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } + + if (!_egl_display && supports_platform_device && supports_device_enumeration) { + PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = + (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); + + EGLint num_devices = 0; + if (eglQueryDevicesEXT != nullptr && + eglQueryDevicesEXT(0, nullptr, &num_devices) && + num_devices > 0) { + EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices); + eglQueryDevicesEXT(num_devices, devices, &num_devices); + + if (egldisplay_cat.is_debug()) { + egldisplay_cat.debug() + << "Found " << num_devices << " EGL devices.\n"; + } + + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + + if (eglGetPlatformDisplayEXT != nullptr) { + for (EGLint i = 0; i < num_devices && !_egl_display; ++i) { + _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr); + + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.warning() + << "Couldn't initialize EGL platform display " << i << ": " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } } } } diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 78e739243c..7578e0de64 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -208,10 +208,22 @@ set_owner(PyObject *owner) { #ifndef NDEBUG if (owner != Py_None) { PyObject *add = PyObject_GetAttrString(owner, "_addTask"); + PyErr_Clear(); PyObject *clear = PyObject_GetAttrString(owner, "_clearTask"); + PyErr_Clear(); - if (add == nullptr || !PyCallable_Check(add) || - clear == nullptr || !PyCallable_Check(clear)) { + bool valid_add = false; + if (add != nullptr) { + valid_add = PyCallable_Check(add); + Py_DECREF(add); + } + bool valid_clear = false; + if (clear != nullptr) { + valid_clear = PyCallable_Check(clear); + Py_DECREF(clear); + } + + if (!valid_add || !valid_clear) { Dtool_Raise_TypeError("owner object should have _addTask and _clearTask methods"); return; } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 180b29ba40..c1155efa05 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -10691,7 +10691,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgba: case Texture::F_rgbm: #ifndef OPENGLES_1 - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGBA16F; } else #endif @@ -10757,7 +10758,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { #endif // OPENGLES #ifndef OPENGLES case Texture::F_rgba16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGBA16F; } else if (Texture::is_unsigned(component_type)) { return GL_RGBA16; @@ -10777,6 +10779,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgb: switch (component_type) { case Texture::T_float: return GL_RGB16F; + case Texture::T_half_float: return GL_RGB16F; #ifndef OPENGLES case Texture::T_unsigned_short: return GL_RGB16; case Texture::T_short: return GL_RGB16_SNORM; @@ -10813,7 +10816,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgb12: return GL_RGB12; case Texture::F_rgb16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGB16F; } else if (Texture::is_unsigned(component_type)) { return GL_RGB16; @@ -10836,7 +10840,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return GL_RG16F_EXT; #elif !defined(OPENGLES_1) case Texture::F_r16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_R16F; } else if (Texture::is_unsigned(component_type)) { return GL_R16; @@ -10844,7 +10849,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return GL_R16_SNORM; } case Texture::F_rg16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RG16F; } else if (Texture::is_unsigned(component_type)) { return GL_RG16; diff --git a/panda/src/mathutil/frustum_src.I b/panda/src/mathutil/frustum_src.I index f884b29f45..a0f1a8f9d9 100644 --- a/panda/src/mathutil/frustum_src.I +++ b/panda/src/mathutil/frustum_src.I @@ -66,12 +66,7 @@ make_ortho(FLOATTYPE fnear, FLOATTYPE ffar, FLOATTYPE l, FLOATTYPE r, } /** - * Behaves like gluPerspective (Aspect = width/height, Yfov in degrees) aspect - * +------------+ | | 1 | | yfov | | - * +------------+ - * - * -------+------ \ | \ | \ | \ | \ | \| W yfov - * + * Behaves like gluPerspective (Aspect = width/height, Yfov in degrees) */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective_hfov(FLOATTYPE hfov, FLOATTYPE aspect, FLOATTYPE fnear, @@ -84,7 +79,9 @@ make_perspective_hfov(FLOATTYPE hfov, FLOATTYPE aspect, FLOATTYPE fnear, _b = -_t; } - +/** + * + */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective_vfov(FLOATTYPE yfov, FLOATTYPE aspect, FLOATTYPE fnear, FLOATTYPE ffar) { @@ -96,7 +93,9 @@ make_perspective_vfov(FLOATTYPE yfov, FLOATTYPE aspect, FLOATTYPE fnear, _l = -_r; } - +/** + * + */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective(FLOATTYPE xfov, FLOATTYPE yfov, FLOATTYPE fnear, FLOATTYPE ffar) { diff --git a/panda/src/tinydisplay/tinyGraphicsBuffer.cxx b/panda/src/tinydisplay/tinyGraphicsBuffer.cxx index ea8e8241a6..47c0327f1b 100644 --- a/panda/src/tinydisplay/tinyGraphicsBuffer.cxx +++ b/panda/src/tinydisplay/tinyGraphicsBuffer.cxx @@ -89,6 +89,15 @@ end_frame(FrameMode mode, Thread *current_thread) { } } +/** + * + */ +void TinyGraphicsBuffer:: +set_size(int x, int y) { + GraphicsBuffer::set_size(x, y); + create_frame_buffer(); +} + /** * Closes the buffer right now. Called from the buffer thread. */ diff --git a/panda/src/tinydisplay/tinyGraphicsBuffer.h b/panda/src/tinydisplay/tinyGraphicsBuffer.h index 79c6e8c5e5..e1fe665959 100644 --- a/panda/src/tinydisplay/tinyGraphicsBuffer.h +++ b/panda/src/tinydisplay/tinyGraphicsBuffer.h @@ -35,6 +35,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); + virtual void set_size(int x, int y); + INLINE ZBuffer *get_frame_buffer(); protected: diff --git a/tests/bullet/test_bullet_bam.py b/tests/bullet/test_bullet_bam.py index ae20f2d47a..d26a6c4117 100644 --- a/tests/bullet/test_bullet_bam.py +++ b/tests/bullet/test_bullet_bam.py @@ -133,6 +133,26 @@ def test_sphere_shape(): assert shape.radius == shape2.radius +def test_convex_shape(): + shape = bullet.BulletConvexHullShape() + shape.add_array([ + (-1.0, -1.0, -1.0), + (1.0, -1.0, -1.0), + (-1.0, 1.0, -1.0), + (-1.0, -1.0, 1.0), + (1.0, 1.0, -1.0), + (1.0, -1.0, 1.0), + (-1.0, 1.0, 1.0), + (1.0, 1.0, 1.0), + ]) + shape.margin = 0.5 + + shape2 = reconstruct(shape) + + assert type(shape) is type(shape2) + assert shape.margin == shape2.margin + + def test_ghost(): node = bullet.BulletGhostNode("some ghost node")