@@ -503,6 +503,28 @@ bool ViewProviderAssembly::tryMouseMove(const SbVec2s& cursorPos, Gui::View3DInv
503503 Base::Placement jcsPlcRelativeToPart = plc.inverse () * jcsGlobalPlc;
504504 plc = rotatedGlovalJcsPlc * jcsPlcRelativeToPart.inverse ();
505505 }
506+ else if (dragMode == DragMode::Ball) {
507+ Base::Vector3d center = jcsGlobalPlc.getPosition ();
508+ // Vectors from joint center to initial click and current drag position
509+ Base::Vector3d u = initialPosition - center;
510+ Base::Vector3d v = newPos - center;
511+
512+ // Ensure vectors are valid to prevent singularities
513+ if (u.Length () > Precision::Confusion () && v.Length () > Precision::Confusion ()) {
514+ // Calculate rotation that moves vector u to v
515+ Base::Rotation rot;
516+ rot.setValue (u, v);
517+
518+ // Apply this rotation to the global joint placement (around the joint center)
519+ Base::Placement rotatedGlobalJcsPlc = jcsGlobalPlc;
520+ rotatedGlobalJcsPlc.setRotation (rot * jcsGlobalPlc.getRotation ());
521+
522+ // Calculate the initial offset of the part relative to the joint
523+ // and apply the new global joint placement to find the new part placement.
524+ Base::Placement jcsPlcRelativeToPart = plc.inverse () * jcsGlobalPlc;
525+ plc = rotatedGlobalJcsPlc * jcsPlcRelativeToPart.inverse ();
526+ }
527+ }
506528 else if (dragMode == DragMode::TranslationOnAxis) {
507529 Base::Vector3d pos = plc.getPosition () + (newPos - initialPosition);
508530 plc.setPosition (pos);
@@ -942,7 +964,7 @@ ViewProviderAssembly::DragMode ViewProviderAssembly::findDragMode()
942964 return DragMode::TranslationOnAxisAndRotationOnePlane;
943965 }
944966 else if (jointType == JointType::Ball) {
945- // return DragMode::Ball;
967+ return DragMode::Ball;
946968 }
947969 else if (jointType == JointType::Distance) {
948970 // depends on the type of distance. For example plane-plane:
0 commit comments