From 9a2203b9bbf7e8c0da802c2317eca3fdd4a3af36 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 25 Feb 2025 17:32:44 +0100 Subject: [PATCH 01/14] pstats: Backport fix for crash when receiving frames out of order --- pandatool/src/pstatserver/pStatThreadData.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandatool/src/pstatserver/pStatThreadData.cxx b/pandatool/src/pstatserver/pStatThreadData.cxx index bef18c8a24..1df4e7c0e7 100644 --- a/pandatool/src/pstatserver/pStatThreadData.cxx +++ b/pandatool/src/pstatserver/pStatThreadData.cxx @@ -290,6 +290,14 @@ record_new_frame(int frame_number, PStatFrameData *frame_data) { } int index = frame_number - _first_frame_number; + + // It's possible to receive frames out of order. + while (index < 0) { + _frames.push_front(nullptr); + ++index; + --_first_frame_number; + } + nassertv(index >= 0 && index < (int)_frames.size()); if (_frames[index] != nullptr) { From fcf619d6067ba6d8e072b43a3ec9a4d1e1fc8f2d Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 25 Feb 2025 17:33:34 +0100 Subject: [PATCH 02/14] Update version numbers to 1.10.16 --- dtool/PandaVersion.pp | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dtool/PandaVersion.pp b/dtool/PandaVersion.pp index c3914608fd..e7f75274e7 100644 --- a/dtool/PandaVersion.pp +++ b/dtool/PandaVersion.pp @@ -7,7 +7,7 @@ // place to put this. // Use spaces to separate the major, minor, and sequence numbers here. -#define PANDA_VERSION 1 10 15 +#define PANDA_VERSION 1 10 16 // This variable will be defined to false in the CVS repository, but // scripts that generate source tarballs and/or binary releases for diff --git a/setup.cfg b/setup.cfg index c252d8d575..e8cf51c227 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = Panda3D -version = 1.10.15 +version = 1.10.16 url = https://www.panda3d.org/ description = Panda3D is a framework for 3D rendering and game development for Python and C++ programs. license = Modified BSD License From 47a823b33080a7c7662aa38640ff5db6170aef8c Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 20 Jul 2025 21:46:33 +0200 Subject: [PATCH 03/14] workflow: Update Windows 2019 to 2022 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c12aac6ab..4353c98638 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" strategy: matrix: - os: [ubuntu-20.04, windows-2019, macOS-12] + os: [ubuntu-20.04, windows-2022, macOS-12] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 From 7051aa00c4994fcfd39cb4dc36505ace342dafb8 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 21 Jul 2025 11:59:41 +0200 Subject: [PATCH 04/14] workflow: Update test runners --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4353c98638..166b627189 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,12 +6,12 @@ jobs: if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" strategy: matrix: - os: [ubuntu-20.04, windows-2022, macOS-12] + os: [ubuntu-22.04, windows-2022, macOS-13] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 - name: Install dependencies (Ubuntu) - if: matrix.os == 'ubuntu-20.04' + if: matrix.os == 'ubuntu-22.04' run: | sudo apt-get update sudo apt-get install build-essential bison flex libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev @@ -39,7 +39,7 @@ jobs: - name: Build Python 3.13 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.13 shell: bash run: | @@ -53,7 +53,7 @@ jobs: - name: Build Python 3.12 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.12 shell: bash run: | @@ -67,7 +67,7 @@ jobs: - name: Build Python 3.11 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.11 shell: bash run: | @@ -81,7 +81,7 @@ jobs: - name: Build Python 3.10 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.10 shell: bash run: | @@ -95,7 +95,7 @@ jobs: - name: Build Python 3.9 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.9 shell: bash run: | @@ -109,7 +109,7 @@ jobs: - name: Build Python 3.8 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 - name: Test Python 3.8 shell: bash run: | From 95f16ea778a3df0443151bea34b456bc51cc5a83 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 21 Jul 2025 12:18:20 +0200 Subject: [PATCH 05/14] workflow: Update to MSVC 14.3 / 2022 --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 166b627189..3a341a39a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - name: Build Python 3.13 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.13 shell: bash run: | @@ -53,7 +53,7 @@ jobs: - name: Build Python 3.12 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.12 shell: bash run: | @@ -67,7 +67,7 @@ jobs: - name: Build Python 3.11 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.11 shell: bash run: | @@ -81,7 +81,7 @@ jobs: - name: Build Python 3.10 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.10 shell: bash run: | @@ -95,7 +95,7 @@ jobs: - name: Build Python 3.9 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.9 shell: bash run: | @@ -109,7 +109,7 @@ jobs: - name: Build Python 3.8 shell: bash run: | - python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2 + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.3 - name: Test Python 3.8 shell: bash run: | From 20c9b0d90259c4cea57fc7e83716d5907963c80d Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 10:00:22 +0200 Subject: [PATCH 06/14] workflow: Hack workaround for Ubuntu CI error --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a341a39a5..d3eaf4d7ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,4 +118,5 @@ jobs: - name: Make installer run: | + rm -f built/bin/p3dcparse python makepanda/makepackage.py --verbose --lzma From de4865b3241ded61a88d0501b8dfeac2d1052b31 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 10:01:11 +0200 Subject: [PATCH 07/14] putil: grab GIL while decreffing function --- panda/src/putil/pythonCallbackObject.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/panda/src/putil/pythonCallbackObject.cxx b/panda/src/putil/pythonCallbackObject.cxx index 3e185e8514..3841abcb9d 100644 --- a/panda/src/putil/pythonCallbackObject.cxx +++ b/panda/src/putil/pythonCallbackObject.cxx @@ -60,7 +60,18 @@ PythonCallbackObject(PyObject *function) { */ PythonCallbackObject:: ~PythonCallbackObject() { + // This may be called from the cull or draw thread, so we have to be sure we + // own the GIL. +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); +#endif + Py_DECREF(_function); + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif } /** From 6a9dde43dab53c4c1a9ab291d37ecd091fc5c061 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 11:10:15 +0200 Subject: [PATCH 08/14] workflow: Fix Windows build --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3eaf4d7ef..2feb1aa06e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,7 +116,10 @@ jobs: python -m pip install pytest PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - - name: Make installer + - name: Remove p3dcparse + if: matrix.os == 'ubuntu-22.04' run: | rm -f built/bin/p3dcparse + - name: Make installer + run: | python makepanda/makepackage.py --verbose --lzma From 7d7a08e66f56be6bbba63fe3fd364360b864acd7 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 11:09:07 +0200 Subject: [PATCH 09/14] cppparser: Consider reference types destructible Fixes #1743 --- dtool/src/cppparser/cppReferenceType.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtool/src/cppparser/cppReferenceType.cxx b/dtool/src/cppparser/cppReferenceType.cxx index 42526789a3..c2b914caf2 100644 --- a/dtool/src/cppparser/cppReferenceType.cxx +++ b/dtool/src/cppparser/cppReferenceType.cxx @@ -187,7 +187,7 @@ is_copy_constructible() const { */ bool CPPReferenceType:: is_destructible() const { - return false; + return true; } /** From 41e4cf5d11409c71512996ec3198652543b8a74a Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 14:54:08 +0200 Subject: [PATCH 10/14] event: Fix `await gather()` returning first item instead of tuple Fixes #1738 --- panda/src/event/asyncFuture_ext.cxx | 23 ++++++++++++++++++++-- tests/event/test_futures.py | 30 ++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index 525757d618..28753dd924 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -167,8 +167,27 @@ static PyObject *gen_next(PyObject *self) { } else { PyObject *result = get_done_result(future); if (result != nullptr) { - Py_INCREF(PyExc_StopIteration); - PyErr_Restore(PyExc_StopIteration, result, nullptr); + // See python/cpython#101578 - PyErr_SetObject has a special case where + // it interprets a tuple specially, so we bypass that by creating the + // exception directly. +#if PY_VERSION_HEX >= 0x030C0000 // 3.12 + PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result); + if (LIKELY(exc != nullptr)) { + // This function steals a reference to exc. + PyErr_SetRaisedException(exc); + } +#else + if (PyTuple_Check(result)) { + PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result); + if (LIKELY(exc != nullptr)) { + PyErr_SetObject(PyExc_StopIteration, exc); + Py_DECREF(exc); + } + } else { + Py_INCREF(PyExc_StopIteration); + PyErr_Restore(PyExc_StopIteration, result, nullptr); + } +#endif } return nullptr; } diff --git a/tests/event/test_futures.py b/tests/event/test_futures.py index 2334549eef..db016ae8d3 100644 --- a/tests/event/test_futures.py +++ b/tests/event/test_futures.py @@ -10,6 +10,21 @@ else: CancelledError = Exception +def check_result(fut, expected): + """Asserts the result of the future is the expected value.""" + + if fut.result() != expected: + return False + + # Make sure that await also returns the values properly + with pytest.raises(StopIteration) as e: + next(fut.__await__()) + if e.value.value != expected: + return False + + return True + + def test_future_cancelled(): fut = core.AsyncFuture() @@ -205,15 +220,20 @@ def test_future_result(): ep = core.EventParameter(0.5) fut = core.AsyncFuture() fut.set_result(ep) - assert fut.result() == 0.5 - assert fut.result() == 0.5 + assert check_result(fut, 0.5) + assert check_result(fut, 0.5) # Store TypedObject dg = core.Datagram(b"test") fut = core.AsyncFuture() fut.set_result(dg) - assert fut.result() == dg - assert fut.result() == dg + assert check_result(fut, dg) + assert check_result(fut, dg) + + # Store tuple + fut = core.AsyncFuture() + fut.set_result((1, 2)) + assert check_result(fut, (1, 2)) # Store arbitrary Python object obj = object() @@ -250,7 +270,7 @@ def test_future_gather(): assert gather.done() assert not gather.cancelled() - assert tuple(gather.result()) == (1, 2) + assert check_result(gather, (1, 2)) def test_future_gather_cancel_inner(): From 6ef4699a486a1f9a9eecd48abf9f4eb395cc415b Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 15:10:31 +0200 Subject: [PATCH 11/14] collide: Fix potential use-after-free with transform cache disabled Fixes #1733 --- panda/src/collide/collisionBox.cxx | 15 +++++++++----- panda/src/collide/collisionCapsule.cxx | 15 +++++++++----- panda/src/collide/collisionFloorMesh.cxx | 8 ++++++-- panda/src/collide/collisionInvSphere.cxx | 18 +++++++++++------ panda/src/collide/collisionPlane.cxx | 21 +++++++++++++------- panda/src/collide/collisionPolygon.cxx | 18 +++++++++++------ panda/src/collide/collisionSphere.cxx | 25 +++++++++++++++--------- 7 files changed, 80 insertions(+), 40 deletions(-) diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 5ec26a705e..e14030212e 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -419,7 +419,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -462,7 +463,8 @@ PT(CollisionEntry) CollisionBox:: test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -511,7 +513,8 @@ PT(CollisionEntry) CollisionBox:: test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *seg; DCAST_INTO_R(seg, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = seg->get_point_a() * wrt_mat; LPoint3 from_extent = seg->get_point_b() * wrt_mat; @@ -566,7 +569,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { const CollisionCapsule *capsule; DCAST_INTO_R(capsule, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -711,7 +715,8 @@ test_intersection_from_box(const CollisionEntry &entry) const { const CollisionBox *box; DCAST_INTO_R(box, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center; LVector3 from_extents = box->get_dimensions() * 0.5f; diff --git a/panda/src/collide/collisionCapsule.cxx b/panda/src/collide/collisionCapsule.cxx index 91ab319735..5a0a344552 100644 --- a/panda/src/collide/collisionCapsule.cxx +++ b/panda/src/collide/collisionCapsule.cxx @@ -226,7 +226,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -274,7 +275,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -335,7 +337,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = segment->get_point_a() * wrt_mat; LPoint3 from_b = segment->get_point_b() * wrt_mat; @@ -402,7 +405,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { LPoint3 into_a = _a; LVector3 into_direction = _b - into_a; - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -463,7 +467,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { const CollisionParabola *parabola; DCAST_INTO_R(parabola, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); // Convert the parabola into local coordinate space. LParabola local_p(parabola->get_parabola()); diff --git a/panda/src/collide/collisionFloorMesh.cxx b/panda/src/collide/collisionFloorMesh.cxx index 5f0ab0cabc..a2261fd1cb 100644 --- a/panda/src/collide/collisionFloorMesh.cxx +++ b/panda/src/collide/collisionFloorMesh.cxx @@ -130,7 +130,9 @@ PT(CollisionEntry) CollisionFloorMesh:: test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - LPoint3 from_origin = ray->get_origin() * entry.get_wrt_mat(); + + CPT(TransformState) wrt_space = entry.get_wrt_space(); + LPoint3 from_origin = ray->get_origin() * wrt_space->get_mat(); double fx = from_origin[0]; double fy = from_origin[1]; @@ -195,7 +197,9 @@ PT(CollisionEntry) CollisionFloorMesh:: test_intersection_from_sphere(const CollisionEntry &entry) const { const CollisionSphere *sphere; DCAST_INTO_R(sphere, entry.get_from(), nullptr); - LPoint3 from_origin = sphere->get_center() * entry.get_wrt_mat(); + + CPT(TransformState) wrt_space = entry.get_wrt_space(); + LPoint3 from_origin = sphere->get_center() * wrt_space->get_mat(); double fx = from_origin[0]; double fy = from_origin[1]; diff --git a/panda/src/collide/collisionInvSphere.cxx b/panda/src/collide/collisionInvSphere.cxx index 1428078d09..097de7245f 100644 --- a/panda/src/collide/collisionInvSphere.cxx +++ b/panda/src/collide/collisionInvSphere.cxx @@ -94,7 +94,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { const CollisionSphere *sphere; DCAST_INTO_R(sphere, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_center = sphere->get_center() * wrt_mat; LVector3 from_radius_v = @@ -146,7 +147,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -187,7 +189,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -230,7 +233,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = segment->get_point_a() * wrt_mat; LPoint3 from_b = segment->get_point_b() * wrt_mat; @@ -296,7 +300,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { const CollisionCapsule *capsule; DCAST_INTO_R(capsule, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -351,7 +356,8 @@ test_intersection_from_box(const CollisionEntry &entry) const { const CollisionBox *box; DCAST_INTO_R(box, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 center = get_center(); PN_stdfloat radius_sq = get_radius(); diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index 2e174d4aa8..90abeb62f9 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -109,7 +109,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { const CollisionSphere *sphere; DCAST_INTO_R(sphere, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_center = sphere->get_center() * wrt_mat; LVector3 from_radius_v = @@ -148,7 +149,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -193,7 +195,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -245,7 +248,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = segment->get_point_a() * wrt_mat; LPoint3 from_b = segment->get_point_b() * wrt_mat; @@ -302,7 +306,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { const CollisionCapsule *capsule; DCAST_INTO_R(capsule, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -373,7 +378,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { const CollisionParabola *parabola; DCAST_INTO_R(parabola, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); // Convert the parabola into local coordinate space. LParabola local_p(parabola->get_parabola()); @@ -439,7 +445,8 @@ test_intersection_from_box(const CollisionEntry &entry) const { const CollisionBox *box; DCAST_INTO_R(box, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_center = box->get_center() * wrt_mat; LVector3 from_extents = box->get_dimensions() * 0.5f; diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index eafffdde90..33cf66bc87 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -552,7 +552,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -620,7 +621,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -693,7 +695,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = segment->get_point_a() * wrt_mat; LPoint3 from_b = segment->get_point_b() * wrt_mat; @@ -763,7 +766,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { const CollisionCapsule *capsule; DCAST_INTO_R(capsule, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -962,7 +966,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { const CollisionParabola *parabola; DCAST_INTO_R(parabola, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); // Convert the parabola into local coordinate space. LParabola local_p(parabola->get_parabola()); @@ -1049,7 +1054,8 @@ test_intersection_from_box(const CollisionEntry &entry) const { // To make things easier, transform the box into the coordinate space of the // plane. - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LMatrix4 plane_mat = wrt_mat * _to_2d_mat; LPoint3 from_center = box->get_center() * plane_mat; diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index 0d3275ec36..2d65f938cb 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -236,7 +236,8 @@ test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = line->get_origin() * wrt_mat; LVector3 from_direction = line->get_direction() * wrt_mat; @@ -278,10 +279,11 @@ test_intersection_from_box(const CollisionEntry &entry) const { // Instead of transforming the box into the sphere's coordinate space, we do // it the other way around. It's easier that way. - const LMatrix4 &wrt_mat = entry.get_inv_wrt_mat(); + CPT(TransformState) inv_wrt_space = entry.get_inv_wrt_space(); + const LMatrix4 &inv_wrt_mat = inv_wrt_space->get_mat(); - LPoint3 center = wrt_mat.xform_point(_center); - PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared(); + LPoint3 center = inv_wrt_mat.xform_point(_center); + PN_stdfloat radius_sq = inv_wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared(); LPoint3 box_min = box->get_min(); LPoint3 box_max = box->get_max(); @@ -330,7 +332,8 @@ test_intersection_from_box(const CollisionEntry &entry) const { PT(CollisionEntry) new_entry = new CollisionEntry(entry); // To get the interior point, clamp the sphere center to the AABB. - LPoint3 interior = entry.get_wrt_mat().xform_point(center.fmax(box_min).fmin(box_max)); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + LPoint3 interior = wrt_space->get_mat().xform_point(center.fmax(box_min).fmin(box_max)); new_entry->set_interior_point(interior); // Now extrapolate the surface point and normal from that. @@ -352,7 +355,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; @@ -399,7 +403,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = segment->get_point_a() * wrt_mat; LPoint3 from_b = segment->get_point_b() * wrt_mat; @@ -448,7 +453,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const { const CollisionCapsule *capsule; DCAST_INTO_R(capsule, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); LPoint3 from_a = capsule->get_point_a() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat; @@ -504,7 +510,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { const CollisionParabola *parabola; DCAST_INTO_R(parabola, entry.get_from(), nullptr); - const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + CPT(TransformState) wrt_space = entry.get_wrt_space(); + const LMatrix4 &wrt_mat = wrt_space->get_mat(); // Convert the parabola into local coordinate space. LParabola local_p(parabola->get_parabola()); From 85e4d0734d088a941895074b08967761374d1ef1 Mon Sep 17 00:00:00 2001 From: omg-really Date: Mon, 28 Jul 2025 15:14:47 +0200 Subject: [PATCH 12/14] bam2egg: Fix support for more than two tags Fixes #1725 --- panda/src/egg2pg/eggSaver.cxx | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/panda/src/egg2pg/eggSaver.cxx b/panda/src/egg2pg/eggSaver.cxx index 6dbcba16d2..23e932782b 100644 --- a/panda/src/egg2pg/eggSaver.cxx +++ b/panda/src/egg2pg/eggSaver.cxx @@ -1196,34 +1196,16 @@ apply_state_properties(EggRenderMode *egg_render_mode, const RenderState *state) */ bool EggSaver:: apply_tags(EggGroup *egg_group, PandaNode *node) { - std::ostringstream strm; - char delimiter = '\n'; - string delimiter_str(1, delimiter); - node->list_tags(strm, delimiter_str); - - string data = strm.str(); - if (data.empty()) { - return false; - } - bool any_applied = false; - size_t p = 0; - size_t q = data.find(delimiter); - while (q != string::npos) { - string tag = data.substr(p, q); - if (apply_tag(egg_group, node, tag)) { + vector_string keys; + node->get_tag_keys(keys); + + for (size_t i = 0; i < keys.size(); ++i) { + if (apply_tag(egg_group, node, keys[i])) { any_applied = true; } - p = q + 1; - q = data.find(delimiter, p); } - - string tag = data.substr(p); - if (apply_tag(egg_group, node, tag)) { - any_applied = true; - } - return any_applied; } From 0a94971f1ae31d59498a3ea0288c7f2b74075531 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 15:25:32 +0200 Subject: [PATCH 13/14] event: Fix memory leak I just introduced in 41e4cf5 --- panda/src/event/asyncFuture_ext.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index 28753dd924..4bc9f07378 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -172,6 +172,7 @@ static PyObject *gen_next(PyObject *self) { // exception directly. #if PY_VERSION_HEX >= 0x030C0000 // 3.12 PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result); + Py_DECREF(result); if (LIKELY(exc != nullptr)) { // This function steals a reference to exc. PyErr_SetRaisedException(exc); @@ -179,6 +180,7 @@ static PyObject *gen_next(PyObject *self) { #else if (PyTuple_Check(result)) { PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result); + Py_DECREF(result); if (LIKELY(exc != nullptr)) { PyErr_SetObject(PyExc_StopIteration, exc); Py_DECREF(exc); From ab357ea1209fd630c2a214c068d2cd8fe4d7d97c Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Jul 2025 15:29:56 +0200 Subject: [PATCH 14/14] tinydisplay: Try to fix SDL compile errors Fixes #1708 --- .../src/tinydisplay/tinySDLGraphicsWindow.cxx | 21 +++++++++++-------- panda/src/tinydisplay/tinySDLGraphicsWindow.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx b/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx index 9c221846eb..54dd73fb15 100644 --- a/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx @@ -43,7 +43,10 @@ TinySDLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, _pitch = 0; update_pixel_factor(); - add_input_device(GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse")); + PT(GraphicsWindowInputDevice) device = + GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse"); + add_input_device(device); + _input = device.p(); } /** @@ -166,35 +169,35 @@ process_events() { switch(evt.type) { case SDL_KEYDOWN: if (evt.key.keysym.unicode) { - _input_devices[0]->keystroke(evt.key.keysym.unicode); + _input->keystroke(evt.key.keysym.unicode); } button = get_keyboard_button(evt.key.keysym.sym); if (button != ButtonHandle::none()) { - _input_devices[0]->button_down(button); + _input->button_down(button); } break; case SDL_KEYUP: button = get_keyboard_button(evt.key.keysym.sym); if (button != ButtonHandle::none()) { - _input_devices[0]->button_up(button); + _input->button_up(button); } break; case SDL_MOUSEBUTTONDOWN: button = get_mouse_button(evt.button.button); - _input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y); - _input_devices[0]->button_down(button); + _input->set_pointer_in_window(evt.button.x, evt.button.y); + _input->button_down(button); break; case SDL_MOUSEBUTTONUP: button = get_mouse_button(evt.button.button); - _input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y); - _input_devices[0]->button_up(button); + _input->set_pointer_in_window(evt.button.x, evt.button.y); + _input->button_up(button); break; case SDL_MOUSEMOTION: - _input_devices[0]->set_pointer_in_window(evt.motion.x, evt.motion.y); + _input->set_pointer_in_window(evt.motion.x, evt.motion.y); break; case SDL_VIDEORESIZE: diff --git a/panda/src/tinydisplay/tinySDLGraphicsWindow.h b/panda/src/tinydisplay/tinySDLGraphicsWindow.h index 8073663ce5..dc3695a6c0 100644 --- a/panda/src/tinydisplay/tinySDLGraphicsWindow.h +++ b/panda/src/tinydisplay/tinySDLGraphicsWindow.h @@ -63,6 +63,8 @@ private: unsigned int _flags; unsigned int _pitch; + GraphicsWindowInputDevice *_input; + public: static TypeHandle get_class_type() { return _type_handle;