public override void OnMouseMove(Vector2 mouse) { base.OnMouseMove(mouse); if (modify_Activated && !owner.viewportControl.Viewport.MouseRelativeMode) { UpdateCursorTransitionOnScreenBorder(); Vector2 viewportSize = Owner.ViewportControl.Viewport.SizeInPixels.ToVector2(); var camera = owner.viewportControl.Viewport.CameraSettings; Vector2 mouseInPixels = owner.viewportControl.Viewport.MousePosition * viewportSize + cursorTransitionOnScreenBorderOffset; Vector2 mouseStartPositionInPixels = mouseStartPosition * viewportSize; Vector2 offset = mouseInPixels - mouseStartPositionInPixels; Quaternion startRotation = GetStartObjectsRotation(); double scaleFactor = ProjectSettings.Get.TransformToolRotationSensitivity / 150; Quaternion rotationOffset = Quaternion.Identity; if (selectedAxis == Axis.X || selectedAxis == Axis.Y || selectedAxis == Axis.Z || selectedAxis == Axis.Radius) { Radian angle; { Matrix2 m = Matrix2.FromRotate(selectedScreenLineAngle); Vector2 localOffset = m * offset; angle = localOffset.X * scaleFactor; SnapAngle(ref angle); } string zeroStr = 0.0f.ToString("F2"); switch (selectedAxis) { case Axis.X: rotationOffset = new Quaternion(new Vector3(Math.Sin(-angle / 2), 0, 0), Math.Cos(-angle / 2)); rotationOffset = startRotation * rotationOffset.GetNormalize() * startRotation.GetInverse(); helpText = string.Format("[{0} {1} {2}]", ((double)angle.InDegrees()).ToString("F2"), zeroStr, zeroStr); break; case Axis.Y: rotationOffset = new Quaternion(new Vector3(0, Math.Sin(angle / 2), 0), Math.Cos(angle / 2)); rotationOffset = startRotation * rotationOffset.GetNormalize() * startRotation.GetInverse(); helpText = string.Format("[{0} {1} {2}]", zeroStr, ((double)-angle.InDegrees()).ToString("F2"), zeroStr); break; case Axis.Z: rotationOffset = new Quaternion(new Vector3(0, 0, Math.Sin(-angle / 2)), Math.Cos(-angle / 2)); rotationOffset = startRotation * rotationOffset.GetNormalize() * startRotation.GetInverse(); helpText = string.Format("[{0} {1} {2}]", zeroStr, zeroStr, ((double)angle.InDegrees()).ToString("F2")); break; case Axis.Radius: Vector3 cameraRight = Vector3.Cross(camera.Direction, camera.Up); Matrix3 cameraRotation = new Matrix3(camera.Direction, -cameraRight, camera.Up); Matrix3 m = cameraRotation * Matrix3.FromRotateByX(-angle) * cameraRotation.GetInverse(); rotationOffset = m.ToQuaternion(); break; } } else if (selectedAxis == Axis.InnerCircle) { Radian angle1 = offset.X * scaleFactor; Radian angle2 = offset.Y * scaleFactor; SnapAngle(ref angle1); SnapAngle(ref angle2); Vector3 cameraRight = Vector3.Cross(camera.Direction, camera.Up); Matrix3 cameraRotation = new Matrix3(camera.Direction, -cameraRight, camera.Up); Matrix3 m = Matrix3.FromRotateByZ(-angle1) * Matrix3.FromRotateByY(angle2); Matrix3 m2 = cameraRotation * m * cameraRotation.GetInverse(); rotationOffset = m2.ToQuaternion(); } rotationOffset.Normalize(); //update objects if (initialObjectsTransform != null && Owner.Objects.Count == initialObjectsTransform.Length) { Owner.OnRotationModeUpdateObjects(initialObjectsTransform, modifyPosition, rotationOffset); } } }