Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package qt6-quick3dphysics for 
openSUSE:Factory checked in at 2024-03-28 13:54:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qt6-quick3dphysics (Old)
 and      /work/SRC/openSUSE:Factory/.qt6-quick3dphysics.new.1905 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "qt6-quick3dphysics"

Thu Mar 28 13:54:23 2024 rev:13 rq:1162389 version:6.6.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/qt6-quick3dphysics/qt6-quick3dphysics.changes    
2024-02-18 20:24:31.184934172 +0100
+++ 
/work/SRC/openSUSE:Factory/.qt6-quick3dphysics.new.1905/qt6-quick3dphysics.changes
  2024-03-28 14:22:11.978893725 +0100
@@ -1,0 +2,6 @@
+Tue Mar 26 14:26:25 UTC 2024 - Christophe Marin <[email protected]>
+
+- Update to 6.6.3:
+  * https://www.qt.io/blog/qt-6.6.3-released
+
+-------------------------------------------------------------------

Old:
----
  qtquick3dphysics-everywhere-src-6.6.2.tar.xz

New:
----
  qtquick3dphysics-everywhere-src-6.6.3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ qt6-quick3dphysics.spec ++++++
--- /var/tmp/diff_new_pack.kebsfj/_old  2024-03-28 14:22:17.803107980 +0100
+++ /var/tmp/diff_new_pack.kebsfj/_new  2024-03-28 14:22:17.803107980 +0100
@@ -16,7 +16,7 @@
 #
 
 
-%define real_version 6.6.2
+%define real_version 6.6.3
 %define short_version 6.6
 %define tar_name qtquick3dphysics-everywhere-src
 %define tar_suffix %{nil}
@@ -27,7 +27,7 @@
 %endif
 #
 Name:           qt6-quick3dphysics%{?pkg_suffix}
-Version:        6.6.2
+Version:        6.6.3
 Release:        0
 Summary:        Qt 6 Quick3D Physics Extensions
 License:        GPL-3.0-only

++++++ qtquick3dphysics-everywhere-src-6.6.2.tar.xz -> 
qtquick3dphysics-everywhere-src-6.6.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtquick3dphysics-everywhere-src-6.6.2/.cmake.conf 
new/qtquick3dphysics-everywhere-src-6.6.3/.cmake.conf
--- old/qtquick3dphysics-everywhere-src-6.6.2/.cmake.conf       2024-02-10 
01:08:30.000000000 +0100
+++ new/qtquick3dphysics-everywhere-src-6.6.3/.cmake.conf       2024-03-19 
06:09:33.000000000 +0100
@@ -1,2 +1,2 @@
-set(QT_REPO_MODULE_VERSION "6.6.2")
+set(QT_REPO_MODULE_VERSION "6.6.3")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qtquick3dphysics-everywhere-src-6.6.2/.tag 
new/qtquick3dphysics-everywhere-src-6.6.3/.tag
--- old/qtquick3dphysics-everywhere-src-6.6.2/.tag      2024-02-10 
01:08:30.000000000 +0100
+++ new/qtquick3dphysics-everywhere-src-6.6.3/.tag      2024-03-19 
06:09:33.000000000 +0100
@@ -1 +1 @@
-40678c93c7fffca82f5915114def549d52c3b950
+007b89ee9b505428224a0178a443d0bdba6b20fe
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/dependencies.yaml 
new/qtquick3dphysics-everywhere-src-6.6.3/dependencies.yaml
--- old/qtquick3dphysics-everywhere-src-6.6.2/dependencies.yaml 2024-02-10 
01:08:30.000000000 +0100
+++ new/qtquick3dphysics-everywhere-src-6.6.3/dependencies.yaml 2024-03-19 
06:09:33.000000000 +0100
@@ -1,13 +1,13 @@
 dependencies:
   ../qtbase:
-    ref: dec1863c7dc63e5788b0c6c061d36e856a6ae2b2
+    ref: afdec885058c92e24604f398a926297222da06f3
     required: true
   ../qtdeclarative:
-    ref: b3d82373ac90e54ad4cbab0c16709a19a9441beb
+    ref: ab5521fd1a637739c7e91def84caa84426055aff
     required: true
   ../qtquick3d:
-    ref: 6dd4377a636493f28df279b2fe0abcdcaa67e0b0
+    ref: 94144b1fd579627b8f96116e6af362fc43e0ba85
     required: true
   ../qtshadertools:
-    ref: 890783bc860332041cd5526e51a5b28c2042f428
+    ref: 58c70c631af3372ed20e042cf41159c6b754df06
     required: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/examples/quick3dphysics/material/main.qml
 
new/qtquick3dphysics-everywhere-src-6.6.3/examples/quick3dphysics/material/main.qml
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/examples/quick3dphysics/material/main.qml
 2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/examples/quick3dphysics/material/main.qml
 2024-03-19 06:09:33.000000000 +0100
@@ -63,6 +63,8 @@
                 materials: DefaultMaterial {
                     diffuseColor: "green"
                 }
+                castsShadows: false
+                receivesShadows: true
             }
         }
         //! [floor]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxactorbody.cpp
 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxactorbody.cpp
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxactorbody.cpp
  2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxactorbody.cpp
  2024-03-19 06:09:33.000000000 +0100
@@ -24,21 +24,12 @@
 
 QT_BEGIN_NAMESPACE
 
-static const QQuaternion kMinus90YawRotation = QQuaternion::fromEulerAngles(0, 
-90, 0);
-
-static inline bool fuzzyEquals(const physx::PxTransform &a, const 
physx::PxTransform &b)
-{
-    return qFuzzyCompare(a.p.x, b.p.x) && qFuzzyCompare(a.p.y, b.p.y) && 
qFuzzyCompare(a.p.z, b.p.z)
-            && qFuzzyCompare(a.q.x, b.q.x) && qFuzzyCompare(a.q.y, b.q.y)
-            && qFuzzyCompare(a.q.z, b.q.z) && qFuzzyCompare(a.q.w, b.q.w);
-}
-
 static physx::PxTransform getPhysXLocalTransform(const QQuick3DNode *node)
 {
     // Modify transforms to make the PhysX shapes match the QtQuick3D 
conventions
     if (qobject_cast<const QPlaneShape *>(node) != nullptr) {
         // Rotate the plane to make it match the built-in rectangle
-        const QQuaternion rotation = kMinus90YawRotation * node->rotation();
+        const QQuaternion rotation = QPhysicsUtils::kMinus90YawRotation * 
node->rotation();
         return physx::PxTransform(QPhysicsUtils::toPhysXType(node->position()),
                                   QPhysicsUtils::toPhysXType(rotation));
     } else if (auto *hf = qobject_cast<const QHeightFieldShape *>(node)) {
@@ -115,7 +106,7 @@
                 auto poseNew = getPhysXLocalTransform(collisionShapes[i]);
                 auto poseOld = physXShapes[i]->getLocalPose();
 
-                if (!fuzzyEquals(poseNew, poseOld)) {
+                if (!QPhysicsUtils::fuzzyEquals(poseNew, poseOld)) {
                     setShapesDirty(true);
                     break;
                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxstaticbody.cpp
 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxstaticbody.cpp
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxstaticbody.cpp
 2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxstaticbody.cpp
 2024-03-19 06:09:33.000000000 +0100
@@ -14,13 +14,6 @@
 
 QT_BEGIN_NAMESPACE
 
-static inline bool fuzzyEquals(const physx::PxTransform &a, const 
physx::PxTransform &b)
-{
-    return qFuzzyCompare(a.p.x, b.p.x) && qFuzzyCompare(a.p.y, b.p.y) && 
qFuzzyCompare(a.p.z, b.p.z)
-            && qFuzzyCompare(a.q.x, b.q.x) && qFuzzyCompare(a.q.y, b.q.y)
-            && qFuzzyCompare(a.q.z, b.q.z) && qFuzzyCompare(a.q.w, b.q.w);
-}
-
 QPhysXStaticBody::QPhysXStaticBody(QStaticRigidBody *frontEnd) : 
QPhysXRigidBody(frontEnd) { }
 
 DebugDrawBodyType QPhysXStaticBody::getDebugDrawBodyType()
@@ -36,7 +29,7 @@
     const physx::PxTransform poseOld = actor->getGlobalPose();
 
     // For performance we only update static objects if they have been moved
-    if (!fuzzyEquals(poseNew, poseOld))
+    if (!QPhysicsUtils::fuzzyEquals(poseNew, poseOld))
         actor->setGlobalPose(poseNew);
     QPhysXActorBody::sync(deltaTime, transformCache);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxworld.cpp
 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxworld.cpp
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/physxnode/qphysxworld.cpp
      2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/physxnode/qphysxworld.cpp
      2024-03-19 06:09:33.000000000 +0100
@@ -91,8 +91,9 @@
                 QAbstractPhysicsNode *other =
                         static_cast<QAbstractPhysicsNode 
*>(pairHeader.actors[1]->userData);
 
-                if (!trigger || !other || !trigger->m_backendObject || 
!other->m_backendObject
-                    || world->isNodeRemoved(trigger) || 
world->isNodeRemoved(other))
+                if (!trigger || !other || world->isNodeRemoved(trigger)
+                    || world->isNodeRemoved(other) || !trigger->m_backendObject
+                    || !other->m_backendObject)
                     continue;
 
                 const bool triggerReceive =
@@ -130,9 +131,9 @@
                 }
 
                 if (triggerReceive)
-                    trigger->registerContact(other, positions, impulses, 
normals);
+                    world->registerContact(other, trigger, positions, 
impulses, normals);
                 if (otherReceive)
-                    other->registerContact(trigger, positions, impulses, 
normalsInverted);
+                    world->registerContact(trigger, other, positions, 
impulses, normalsInverted);
             }
         }
     };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsutils_p.h 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsutils_p.h
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsutils_p.h  
    2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsutils_p.h  
    2024-03-19 06:09:33.000000000 +0100
@@ -59,6 +59,15 @@
     return physx::PxTransform(QPhysicsUtils::toPhysXType(position),
                               QPhysicsUtils::toPhysXType(rotation));
 }
+
+Q_ALWAYS_INLINE bool fuzzyEquals(const physx::PxTransform &a, const 
physx::PxTransform &b)
+{
+    return qFuzzyCompare(a.p.x, b.p.x) && qFuzzyCompare(a.p.y, b.p.y) && 
qFuzzyCompare(a.p.z, b.p.z)
+            && qFuzzyCompare(a.q.x, b.q.x) && qFuzzyCompare(a.q.y, b.q.y)
+            && qFuzzyCompare(a.q.z, b.q.z) && qFuzzyCompare(a.q.w, b.q.w);
+}
+
+inline const QQuaternion kMinus90YawRotation = QQuaternion::fromEulerAngles(0, 
-90, 0);
 }
 
 #endif // QPHYSICSUTILS_P_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsworld.cpp 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsworld.cpp
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsworld.cpp  
    2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsworld.cpp  
    2024-03-19 06:09:33.000000000 +0100
@@ -146,8 +146,6 @@
 
 Q_LOGGING_CATEGORY(lcQuick3dPhysics, "qt.quick3d.physics");
 
-static const QQuaternion kMinus90YawRotation = QQuaternion::fromEulerAngles(0, 
-90, 0);
-
 /////////////////////////////////////////////////////////////////////////////
 
 class SimulationWorker : public QObject
@@ -308,18 +306,39 @@
 {
     for (auto world : worldManager.worlds) {
         world->m_newPhysicsNodes.removeAll(physicsNode);
+        QMutexLocker locker(&world->m_removedPhysicsNodesMutex);
         if (physicsNode->m_backendObject) {
             Q_ASSERT(physicsNode->m_backendObject->frontendNode == 
physicsNode);
             physicsNode->m_backendObject->frontendNode = nullptr;
             physicsNode->m_backendObject->isRemoved = true;
             physicsNode->m_backendObject = nullptr;
         }
-        QMutexLocker locker(&world->m_removedPhysicsNodesMutex);
         world->m_removedPhysicsNodes.insert(physicsNode);
     }
     worldManager.orphanNodes.removeAll(physicsNode);
 }
 
+void QPhysicsWorld::registerContact(QAbstractPhysicsNode *sender, 
QAbstractPhysicsNode *receiver,
+                                    const QVector<QVector3D> &positions,
+                                    const QVector<QVector3D> &impulses,
+                                    const QVector<QVector3D> &normals)
+{
+    // Since collision callbacks happen in the physx simulation thread we need
+    // to store these callbacks. Otherwise, if an object is deleted in the same
+    // frame a 'onBodyContact' signal is enqueued and a crash will happen.
+    // Therefore we save these contact callbacks and run them at the end of the
+    // physics frame when we know if the objects are deleted or not.
+
+    BodyContact contact;
+    contact.sender = sender;
+    contact.receiver = receiver;
+    contact.positions = positions;
+    contact.impulses = impulses;
+    contact.normals = normals;
+
+    m_registeredContacts.push_back(contact);
+}
+
 QPhysicsWorld::QPhysicsWorld(QObject *parent) : QObject(parent)
 {
     m_inDesignStudio = !qEnvironmentVariableIsEmpty("QML_PUPPET_MODE");
@@ -643,7 +662,7 @@
                 physXShape->getPlaneGeometry(planeGeometry);
                 // Special rotation
                 const QQuaternion rotation =
-                        kMinus90YawRotation * 
QPhysicsUtils::toQtType(localPose.q);
+                        QPhysicsUtils::kMinus90YawRotation * 
QPhysicsUtils::toQtType(localPose.q);
                 localPose = physx::PxTransform(localPose.p, 
QPhysicsUtils::toPhysXType(rotation));
 
                 if (model->geometry() == nullptr) {
@@ -1097,6 +1116,7 @@
 void QPhysicsWorld::frameFinished(float deltaTime)
 {
     matchOrphanNodes();
+    emitContactCallbacks();
     cleanupRemovedNodes();
     for (auto *node : std::as_const(m_newPhysicsNodes)) {
         auto *body = node->createPhysXBackend();
@@ -1127,6 +1147,7 @@
 {
     // Note sure if this is needed but do it anyway
     matchOrphanNodes();
+    emitContactCallbacks();
     cleanupRemovedNodes();
     // Ignore new physics nodes, we find them from the scene node anyway
     m_newPhysicsNodes.clear();
@@ -1209,6 +1230,19 @@
     }
 }
 
+void QPhysicsWorld::emitContactCallbacks()
+{
+    for (const QPhysicsWorld::BodyContact &contact : m_registeredContacts) {
+        if (m_removedPhysicsNodes.contains(contact.sender)
+            || m_removedPhysicsNodes.contains(contact.receiver))
+            continue;
+        contact.receiver->registerContact(contact.sender, contact.positions, 
contact.impulses,
+                                          contact.normals);
+    }
+
+    m_registeredContacts.clear();
+}
+
 physx::PxPhysics *QPhysicsWorld::getPhysics()
 {
     return StaticPhysXObjects::getReference().physics;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsworld_p.h 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsworld_p.h
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/src/quick3dphysics/qphysicsworld_p.h  
    2024-02-10 01:08:30.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/src/quick3dphysics/qphysicsworld_p.h  
    2024-03-19 06:09:33.000000000 +0100
@@ -104,6 +104,10 @@
     static void registerNode(QAbstractPhysicsNode *physicsNode);
     static void deregisterNode(QAbstractPhysicsNode *physicsNode);
 
+    void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode 
*receiver,
+                         const QVector<QVector3D> &positions, const 
QVector<QVector3D> &impulses,
+                         const QVector<QVector3D> &normals);
+
     Q_REVISION(6, 5) QQuick3DNode *viewport() const;
     void setHasIndividualDebugDraw();
     physx::PxControllerManager *controllerManager();
@@ -148,6 +152,16 @@
     void disableDebugDraw();
     void matchOrphanNodes();
     void findPhysicsNodes();
+    void emitContactCallbacks();
+
+    struct BodyContact
+    {
+        QAbstractPhysicsNode *sender = nullptr;
+        QAbstractPhysicsNode *receiver = nullptr;
+        QVector<QVector3D> positions;
+        QVector<QVector3D> impulses;
+        QVector<QVector3D> normals;
+    };
 
     struct DebugModelHolder
     {
@@ -194,6 +208,7 @@
             m_collisionShapeDebugModels;
     QSet<QAbstractPhysicsNode *> m_removedPhysicsNodes;
     QMutex m_removedPhysicsNodesMutex;
+    QList<BodyContact> m_registeredContacts;
 
     QVector3D m_gravity = QVector3D(0.f, -981.f, 0.f);
     float m_typicalLength = 100.f; // 100 cm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/CMakeLists.txt 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/CMakeLists.txt
--- old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/CMakeLists.txt 
2024-02-10 01:08:30.000000000 +0100
+++ new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/CMakeLists.txt 
2024-03-19 06:09:33.000000000 +0100
@@ -1,4 +1,5 @@
 add_subdirectory(callback)
+add_subdirectory(callback_create_delete_node)
 add_subdirectory(changescene)
 add_subdirectory(character)
 add_subdirectory(character_remove)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/Box.qml
 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/Box.qml
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/Box.qml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/Box.qml
    2024-03-19 06:09:33.000000000 +0100
@@ -0,0 +1,21 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick3D
+import QtQuick3D.Physics
+
+DynamicRigidBody {
+    Model {
+        source: "#Cube"
+        materials: PrincipledMaterial {
+            baseColor: "red"
+        }
+    }
+
+    sendContactReports: true
+    receiveContactReports: true
+    onBodyContact: (body, positions, impulses, normals) => {}
+
+    collisionShapes: BoxShape {}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/CMakeLists.txt
 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/CMakeLists.txt
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/CMakeLists.txt
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/CMakeLists.txt
     2024-03-19 06:09:33.000000000 +0100
@@ -0,0 +1,22 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH 
Qt-GPL-exception-1.0
+
+set(PROJECT_NAME "test_auto_callback_create_delete_node")
+
+qt_internal_add_test(${PROJECT_NAME}
+    GUI
+    QMLTEST
+    SOURCES
+        tst_callback_create_delete_node.cpp
+    LIBRARIES
+        Qt::Core
+        Qt::Qml
+    TESTDATA
+        tst_callback_create_delete_node.qml
+        Box.qml
+    BUILTIN_TESTDATA
+)
+
+if(QT_BUILD_STANDALONE_TESTS)
+    qt_import_qml_plugins(${PROJECT_NAME})
+endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.cpp
 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.cpp
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.cpp
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.cpp
        2024-03-19 06:09:33.000000000 +0100
@@ -0,0 +1,21 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH 
Qt-GPL-exception-1.0
+
+#include <QtQuickTest/quicktest.h>
+class tst_callback_create_delete_node : public QObject
+{
+    Q_OBJECT
+private slots:
+    void skiptest() { QSKIP("This test will fail, skipping."); };
+};
+int main(int argc, char **argv)
+{
+    if (!qEnvironmentVariableIsEmpty("QEMU_LD_PREFIX")) {
+        qWarning("This test is unstable on QEMU, so it will be skipped.");
+        tst_callback_create_delete_node skip;
+        return QTest::qExec(&skip, argc, argv);
+    }
+    QTEST_SET_MAIN_SOURCE_PATH
+    return quick_test_main(argc, argv, "tst_callback_create_delete_node", 
QUICK_TEST_SOURCE_DIR);
+}
+#include "tst_callback_create_delete_node.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.qml
 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.qml
--- 
old/qtquick3dphysics-everywhere-src-6.6.2/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.qml
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/qtquick3dphysics-everywhere-src-6.6.3/tests/auto/callback_create_delete_node/tst_callback_create_delete_node.qml
        2024-03-19 06:09:33.000000000 +0100
@@ -0,0 +1,104 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+// Tests that removing and adding objects with active contact callbacks
+// does not crash. QTBUG-121033
+
+import QtCore
+import QtTest
+import QtQuick3D
+import QtQuick3D.Physics
+import QtQuick3D.Physics.Helpers
+import QtQuick
+
+Item {
+    width: 800
+    height: 600
+    visible: true
+
+    PhysicsWorld {
+        scene: viewport.scene
+    }
+
+    View3D {
+        id: viewport
+        width: parent.width
+        height: parent.height
+        focus: true
+
+        environment: SceneEnvironment {
+            antialiasingMode: SceneEnvironment.MSAA
+            backgroundMode: SceneEnvironment.Color
+            clearColor: "#f0f0f0"
+        }
+
+        PerspectiveCamera {
+            id: camera
+            position: Qt.vector3d(-400, 500, 1000)
+            eulerRotation: Qt.vector3d(-20, -20, 0)
+            clipFar: 5000
+            clipNear: 1
+        }
+
+        DirectionalLight {
+            eulerRotation: Qt.vector3d(-45, 45, 0)
+        }
+
+        Node {
+            id: shapeSpawner
+            property var instancesBoxes: []
+            property var boxComponent: Qt.createComponent("Box.qml")
+            property int numSpawns: 0
+
+            function createStack() {
+                let size = 10
+
+                for (var i = 0; i < 3; i++) {
+                    for (var j = 0; j < 3; j++) {
+                        let center = Qt.vector3d(j*100, 100*i, 0)
+                        let box = boxComponent.incubateObject(shapeSpawner, {
+                                                                  "position": 
center,
+                                                              })
+                        instancesBoxes.push(box)
+                    }
+                }
+
+                numSpawns = numSpawns + 1;
+            }
+
+            function reset() {
+                // Only run method if previous stack has been created fully
+                for (var i = 0; i < instancesBoxes.length; i++)
+                    if (!instancesBoxes[i].object)
+                        return
+
+                instancesBoxes.forEach(box => {
+                                           box.object.collisionShapes = []
+                                           box.object.destroy()
+                                       })
+                instancesBoxes = []
+
+                shapeSpawner.createStack()
+            }
+        }
+    }
+
+    FrameAnimation {
+        property int frame: 0
+        running: true
+        onTriggered: {
+            frame = frame + 1;
+            if (frame % 2 == 0) {
+                shapeSpawner.reset()
+            }
+        }
+    }
+
+    TestCase {
+        name: "100 cycles"
+        when: shapeSpawner.numSpawns > 100
+        function triggered() {}
+    }
+
+}
+

Reply via email to