diff --git a/README.md b/README.md index bf5e918921..41c29411d3 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Installing Panda3D ================== The latest Panda3D SDK can be downloaded from -[this page](https://www.panda3d.org/download/sdk-1-10-5/). +[this page](https://www.panda3d.org/download/sdk-1-10-6/). If you are familiar with installing Python packages, you can use -the following comand: +the following command: ```bash pip install panda3d @@ -64,8 +64,8 @@ depending on whether you are on a 32-bit or 64-bit system, or you can [click here](https://github.com/rdb/panda3d-thirdparty) for instructions on building them from source. -- https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-win64.zip -- https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-win32.zip +- https://www.panda3d.org/download/panda3d-1.10.6/panda3d-1.10.6-tools-win64.zip +- https://www.panda3d.org/download/panda3d-1.10.6/panda3d-1.10.6-tools-win32.zip After acquiring these dependencies, you can build Panda3D from the command prompt using the following command. Change the `--msvc-version` option based @@ -117,7 +117,7 @@ sudo apt-get install build-essential pkg-config fakeroot python-dev libpng-dev l ``` Once Panda3D has built, you can either install the .deb or .rpm package that -it produced, depending on which Linux distribution you are using. For example, +is produced, depending on which Linux distribution you are using. For example, to install the package on Debian or Ubuntu, use this: ```bash @@ -136,7 +136,7 @@ macOS ----- On macOS, you will need to download a set of precompiled thirdparty packages in order to -compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-mac.tar.gz). +compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.6/panda3d-1.10.6-tools-mac.tar.gz). After placing the thirdparty directory inside the panda3d source directory, you may build Panda3D using a command like the following: @@ -212,7 +212,7 @@ Running Tests Install [PyTest](https://docs.pytest.org/en/latest/getting-started.html#installation) and run the `pytest` command. If you have not installed Panda3D, you will -need to configure your enviroment by pointing the `PYTHONPATH` variable at +need to configure your environment by pointing the `PYTHONPATH` variable at the `built` directory. On Linux, you will also need to point the `LD_LIBRARY_PATH` variable at the `built/lib` directory. diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index f706d7e495..8e417f5340 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -1,3 +1,57 @@ +------------------------ RELEASE 1.10.6 ----------------------- + +This is a recommended bugfix release that adds additional stability fixes. + +Stability +* Fix deployment system to work properly with pip 20 +* Fix multithreading crash when garbage collecting render states (#499) +* Fix crashes when hotplugging USB device on macOS Catalina (#847) +* Fix crash when using Python OpenSSL module with wheel build of Panda3D (#851) +* Fix a memory leak in task system in Python 3 (#873) +* Fix detection for convex angles in visible geometry in collision system (#879) +* Fix regression in 1.10.4 when overriding verticalScroll_frameSize (#864) +* Fix DirectScrolledList scrollTo error in Python 3 (#880) + +Shaders +* Fix OpenGL shaders not being properly applied across multiple buffers +* Proper handling of texture rotations applied to normal maps (#808) +* "//Cg profile" no longer affects subsequent shader loads (#863) +* Add support for custom vertex columns when munging points to quads (#870) +* Workaround for GLSL p3d_TextureMatrix[] input giving GL error on macOS (#846) +* Fix ShaderTerrainMesh disappearing when enabling compressed-textures + +Input +* Fix MouseWatcherRegion leave event sometimes being fired twice (#858) +* Fix odd behavior when pressing multiple mouse buttons during capture (#843) +* Fix support for dead key input on some X11 servers +* Fix raw key events being sent down repeatedly when holding key on X11 (#874) +* Numpad keys are no longer included in get_keyboard_map() on X11 +* Add labels to some keys in get_keyboard_map() on X11 +* Properly use cursor hotspot when loading custom cursor on macOS (#845) +* Loading custom cursor on macOS now properly resolves against model-path + +Animation +* unloadAnims no longer removes all control effects, only for given anims (#853) +* AnimChannelScalarTable (for morph animations) is now exposed to Python +* It's now possible to create a CharacterSlider with default value + +Pipeline +* Fix assertion errors when model-cache-dir cannot be created (#790) +* Textures with clear colors are no longer stripped from bam files (#844) +* Support texture clear colors in bam files (requires "bam-version 6 45" in PRC) +* Fix bam2egg skinning bug for models with default poses on joints +* bam2egg supports multitexturing and multiple UV sets + +Build system +* Add missing --cggl-incdir and --cggl-libdir options in makepanda +* Reduce library size by not exporting symbols of linked static libraries +* Wheels no longer unnecessarily include libpythonX.Y.a (#839) +* makepanda now auto-disables plug-ins in Config.prc that were not compiled in +* Fix refcounting of returned ReferenceCount-like objects in interrogate +* Fix inability to build a .whl on Ubuntu +* Fix erratic build failure in dcParser code +* Fix compilation using Windows 8.1 SDK + ------------------------ RELEASE 1.10.5 ----------------------- This is a recommended bugfix release, especially for macOS users. diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index c4f6b4e7bb..6814948cea 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -442,10 +442,12 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { LVector3 normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); #ifndef NDEBUG if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001)) { - collide_cat.info() - << "polygon within " << entry.get_into_node_path() - << " has normal " << normal << " of length " << normal.length() - << "\n"; + if (collide_cat.is_info()) { + collide_cat.info() + << "polygon within " << entry.get_into_node_path() + << " has normal " << normal << " of length " << normal.length() + << "\n"; + } normal.normalize(); } #endif diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index d28e2d208b..d0d69cfda3 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -9951,9 +9951,11 @@ do_write_datagram_header(CData *cdata, BamWriter *manager, Datagram &me, bool &h << "Unsupported bam-texture-mode: " << (int)file_texture_mode << "\n"; } - if (filename.empty() && do_has_bam_rawdata(cdata)) { - // If we don't have a filename, we have to store rawdata anyway. - has_rawdata = true; + if (filename.empty()) { + if (do_has_bam_rawdata(cdata) || cdata->_has_clear_color) { + // If we don't have a filename, we have to store rawdata anyway. + has_rawdata = true; + } } me.add_string(get_name()); @@ -10023,6 +10025,13 @@ do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) { me.add_uint32(cdata->_simple_ram_image._image.size()); me.append_data(cdata->_simple_ram_image._image, cdata->_simple_ram_image._image.size()); } + + if (manager->get_file_minor_ver() >= 45) { + me.add_bool(cdata->_has_clear_color); + if (cdata->_has_clear_color) { + cdata->_clear_color.write_datagram(me); + } + } } /** @@ -10046,11 +10055,31 @@ do_write_datagram_rawdata(CData *cdata, BamWriter *manager, Datagram &me) { me.add_uint8(cdata->_component_type); me.add_uint8(cdata->_component_width); me.add_uint8(cdata->_ram_image_compression); - me.add_uint8(cdata->_ram_images.size()); - for (size_t n = 0; n < cdata->_ram_images.size(); ++n) { - me.add_uint32(cdata->_ram_images[n]._page_size); - me.add_uint32(cdata->_ram_images[n]._image.size()); - me.append_data(cdata->_ram_images[n]._image, cdata->_ram_images[n]._image.size()); + + if (cdata->_ram_images.empty() && cdata->_has_clear_color && + manager->get_file_minor_ver() < 45) { + // For older .bam versions that don't support clear colors, make up a RAM + // image. + int image_size = do_get_expected_ram_image_size(cdata); + me.add_uint8(1); + me.add_uint32(do_get_expected_ram_page_size(cdata)); + me.add_uint32(image_size); + + // Fill the image with the clear color. + unsigned char pixel[16]; + const int pixel_size = do_get_clear_data(cdata, pixel); + nassertv(pixel_size > 0); + + for (int i = 0; i < image_size; i += pixel_size) { + me.append_data(pixel, pixel_size); + } + } else { + me.add_uint8(cdata->_ram_images.size()); + for (size_t n = 0; n < cdata->_ram_images.size(); ++n) { + me.add_uint32(cdata->_ram_images[n]._page_size); + me.add_uint32(cdata->_ram_images[n]._image.size()); + me.append_data(cdata->_ram_images[n]._image, cdata->_ram_images[n]._image.size()); + } } } @@ -10268,6 +10297,13 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) { cdata->_simple_ram_image._page_size = u_size; cdata->inc_simple_image_modified(); } + + if (manager->get_file_minor_ver() >= 45) { + cdata->_has_clear_color = scan.get_bool(); + if (cdata->_has_clear_color) { + cdata->_clear_color.read_datagram(scan); + } + } } /** diff --git a/panda/src/grutil/shaderTerrainMesh.cxx b/panda/src/grutil/shaderTerrainMesh.cxx index 3aaaccc8b0..4683ee6ba7 100644 --- a/panda/src/grutil/shaderTerrainMesh.cxx +++ b/panda/src/grutil/shaderTerrainMesh.cxx @@ -206,6 +206,7 @@ bool ShaderTerrainMesh::do_check_heightfield() { void ShaderTerrainMesh::do_init_data_texture() { _data_texture = new Texture("TerrainDataTexture"); _data_texture->setup_2d_texture(stm_max_chunk_count, stm_max_views, Texture::T_float, Texture::F_rgba32); + _data_texture->set_compression(Texture::CM_off); _data_texture->set_clear_color(LVector4(0)); _data_texture->clear_image(); } diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index e21dadbc14..33ce0b9f38 100644 --- a/panda/src/putil/bam.h +++ b/panda/src/putil/bam.h @@ -32,6 +32,7 @@ static const unsigned short _bam_major_ver = 6; // Bumped to major version 6 on 2006-02-11 to factor out PandaNode::CData. static const unsigned short _bam_first_minor_ver = 14; +static const unsigned short _bam_last_minor_ver = 45; static const unsigned short _bam_minor_ver = 44; // Bumped to minor version 14 on 2007-12-19 to change default ColorAttrib. // Bumped to minor version 15 on 2008-04-09 to add TextureAttrib::_implicit_sort. @@ -64,5 +65,6 @@ static const unsigned short _bam_minor_ver = 44; // Bumped to minor version 42 on 2016-04-08 to expand ColorBlendAttrib. // Bumped to minor version 43 on 2018-12-06 to expand BillboardEffect and CompassEffect. // Bumped to minor version 44 on 2018-12-23 to rename CollisionTube to CollisionCapsule. +// Bumped to minor version 45 on 2020-03-18 to add Texture::_clear_color. #endif diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index db360ae249..2c9f0958ea 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -107,7 +107,7 @@ init() { // can't safely load the file. if (_file_major != _bam_major_ver || _file_minor < _bam_first_minor_ver || - _file_minor > _bam_minor_ver) { + _file_minor > _bam_last_minor_ver) { bam_cat.error() << "Bam file is version " << _file_major << "." << _file_minor << ".\n"; @@ -120,7 +120,7 @@ init() { bam_cat.error() << "This program can only load version " << _bam_major_ver << "." << _bam_first_minor_ver << " through " - << _bam_major_ver << "." << _bam_minor_ver << " bams.\n"; + << _bam_major_ver << "." << _bam_last_minor_ver << " bams.\n"; } return false; diff --git a/panda/src/putil/bamWriter.cxx b/panda/src/putil/bamWriter.cxx index 3de731d27d..63a86efbbf 100644 --- a/panda/src/putil/bamWriter.cxx +++ b/panda/src/putil/bamWriter.cxx @@ -80,18 +80,18 @@ BamWriter(DatagramSink *target) : _file_minor = 21; bam_version.set_string_value("6 21"); - } else if (_file_major > _bam_major_ver || _file_minor > _bam_minor_ver) { + } else if (_file_major > _bam_major_ver || _file_minor > _bam_last_minor_ver) { util_cat.error() << "bam-version is set to " << bam_version << ", but this version of " "Panda3D cannot produce .bam files newer than " << _bam_major_ver - << "." << _bam_minor_ver << ". Set bam-version to a supported " + << "." << _bam_last_minor_ver << ". Set bam-version to a supported " "version or leave it blank to write version " << _bam_major_ver - << "." << _bam_minor_ver << " files.\n"; + << "." << _bam_last_minor_ver << " files.\n"; _file_major = _bam_major_ver; - _file_minor = _bam_minor_ver; + _file_minor = _bam_last_minor_ver; bam_version.set_word(0, _bam_major_ver); - bam_version.set_word(1, _bam_minor_ver); + bam_version.set_word(1, _bam_last_minor_ver); } } else { _file_major = _bam_major_ver; @@ -157,7 +157,7 @@ init() { _long_pta_id = false; nassertr_always(_file_major == _bam_major_ver, false); - nassertr_always(_file_minor <= _bam_minor_ver && _file_minor >= 21, false); + nassertr_always(_file_minor <= _bam_last_minor_ver && _file_minor >= 21, false); _file_endian = bam_endian; _file_texture_mode = bam_texture_mode; diff --git a/panda/src/tform/mouseWatcher.cxx b/panda/src/tform/mouseWatcher.cxx index 74cb7692d3..44258bfe45 100644 --- a/panda/src/tform/mouseWatcher.cxx +++ b/panda/src/tform/mouseWatcher.cxx @@ -990,9 +990,6 @@ release(ButtonHandle button) { // Button up. Send the up event associated with the region(s) we were // over when the button went down. - // There is some danger of losing button-up events here. If more than one - // button goes down together, we won't detect both of the button-up events - // properly. if (_preferred_button_down_region != nullptr) { param.set_outside(_preferred_button_down_region != _preferred_region); _preferred_button_down_region->release(param); @@ -1000,8 +997,22 @@ release(ButtonHandle button) { _preferred_button_down_region, button); } - _button_down = false; - _preferred_button_down_region = nullptr; + // Do not stop capturing until the last mouse button has gone up. This is + // needed to prevent stopping the capture until the capturing region has + // finished processing all the releases. + bool has_button = false; + for (size_t i = 0; i < MouseButton::num_mouse_buttons; ++i) { + if (MouseButton::_buttons[i] != button && + _current_buttons_down.get_bit(MouseButton::_buttons[i].get_index())) { + has_button = true; + } + } + + if (!has_button) { + // The last mouse button went up. + _button_down = false; + _preferred_button_down_region = nullptr; + } } else { // It's a keyboard button; therefore, send the event to every region that diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 819b559f44..4372ce59ec 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -310,10 +310,6 @@ process_events() { bool changed_properties = false; while (XCheckIfEvent(_display, &event, check_event, (char *)this)) { - if (XFilterEvent(&event, None)) { - continue; - } - if (got_keyrelease_event) { // If a keyrelease event is immediately followed by a matching keypress // event, that's just key repeat and we should treat the two events @@ -324,22 +320,42 @@ process_events() { if (event.type == KeyPress && event.xkey.keycode == keyrelease_event.keycode && (event.xkey.time - keyrelease_event.time <= 1)) { - // In particular, we only generate down messages for the repeated - // keys, not down-and-up messages. - handle_keystroke(event.xkey); + if (!XFilterEvent(&event, None)) { + // In particular, we only generate down messages for the repeated + // keys, not down-and-up messages. + handle_keystroke(event.xkey); - // We thought about not generating the keypress event, but we need - // that repeat for backspace. Rethink later. - handle_keyrepeat(event.xkey); + // We thought about not generating the keypress event, but we need + // that repeat for backspace. Rethink later. + handle_keypress(event.xkey); + } continue; } else { // This keyrelease event is not immediately followed by a matching // keypress event, so it's a genuine release. + ButtonHandle raw_button = map_raw_button(keyrelease_event.keycode); + if (raw_button != ButtonHandle::none()) { + _input->raw_button_up(raw_button); + } + handle_keyrelease(keyrelease_event); } } + // Send out a raw key press event before we do XFilterEvent, which will + // filter out dead keys and such. + if (event.type == KeyPress) { + ButtonHandle raw_button = map_raw_button(event.xkey.keycode); + if (raw_button != ButtonHandle::none()) { + _input->raw_button_down(raw_button); + } + } + + if (XFilterEvent(&event, None)) { + continue; + } + ButtonHandle button; switch (event.type) { @@ -576,6 +592,11 @@ process_events() { if (got_keyrelease_event) { // This keyrelease event is not immediately followed by a matching // keypress event, so it's a genuine release. + ButtonHandle raw_button = map_raw_button(keyrelease_event.keycode); + if (raw_button != ButtonHandle::none()) { + _input->raw_button_up(raw_button); + } + handle_keyrelease(keyrelease_event); } } @@ -1528,41 +1549,6 @@ handle_keypress(XKeyEvent &event) { } _input->button_down(button); } - - if (event.keycode >= 9 && event.keycode <= 135) { - ButtonHandle raw_button = map_raw_button(event.keycode); - if (raw_button != ButtonHandle::none()) { - _input->raw_button_down(raw_button); - } - } -} - -/** - * Generates a keyrepeat corresponding to the indicated X KeyPress event. - */ -void x11GraphicsWindow:: -handle_keyrepeat(XKeyEvent &event) { - if (_properties.get_mouse_mode() != WindowProperties::M_relative) { - _input->set_pointer_in_window(event.x, event.y); - } - - // Now get the raw unshifted button. - ButtonHandle button = get_button(event, false); - if (button != ButtonHandle::none()) { - if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) { - _input->button_down(KeyboardButton::control()); - } - if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) { - _input->button_down(KeyboardButton::shift()); - } - if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) { - _input->button_down(KeyboardButton::alt()); - } - if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) { - _input->button_down(KeyboardButton::meta()); - } - _input->button_down(button); - } } /** @@ -1591,13 +1577,6 @@ handle_keyrelease(XKeyEvent &event) { } _input->button_up(button); } - - if (event.keycode >= 9 && event.keycode <= 135) { - ButtonHandle raw_button = map_raw_button(event.keycode); - if (raw_button != ButtonHandle::none()) { - _input->raw_button_up(raw_button); - } - } } /** @@ -2024,7 +2003,7 @@ map_raw_button(KeyCode key) const { // In any case, this means we can use the same mapping as our raw // input code, which uses evdev directly. int index = key - 8; - if (index >= 0) { + if (index > 0 && index < 128) { return EvdevInputDevice::map_button(index); } #endif diff --git a/panda/src/x11display/x11GraphicsWindow.h b/panda/src/x11display/x11GraphicsWindow.h index 2336fcccc8..e3d4a86382 100644 --- a/panda/src/x11display/x11GraphicsWindow.h +++ b/panda/src/x11display/x11GraphicsWindow.h @@ -59,7 +59,6 @@ protected: virtual void setup_colormap(XVisualInfo *visual); void handle_keystroke(XKeyEvent &event); void handle_keypress(XKeyEvent &event); - void handle_keyrepeat(XKeyEvent &event); void handle_keyrelease(XKeyEvent &event); ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift);