So every time we rotate the viewport, we rotate around some point in 3d space. Can we directly. i.e. without cares about current selected object, transform pivot mode, viewport settings, etc., access to this point, i.e. origin of rotation of the current given viewport 3d in world space (or even in screen space)?
I was trying to ask GPT about this and he came up with this colution:
import bpy
bl_info = {
"name": "Viewport Rotation Point Debugger",
"author": "Your Name",
"version": (1, 0),
"blender": (3, 0, 0),
"location": "Search > Viewport Rotation Point Debugger",
"description": "Prints the 3D rotation point of the viewport camera when rotation starts and a message when it stops.",
"category": "3D View",
}
class ViewportRotationPointDebugger(bpy.types.Operator):
"""Detects viewport camera rotation and prints the rotation point"""
bl_idname = "view3d.rotation_point_debugger"
bl_label = "Viewport Rotation Point Debugger"
bl_options = {'REGISTER'}
is_rotating = False # Track whether the camera is rotating
last_rotation = None # Store the last rotation quaternion
rotation_pivot = None # Store the calculated rotation pivot
def get_rotation_pivot_world(self, context):
"""Returns the rotation pivot point in world space"""
area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
region_3d = area.spaces[0].region_3d
# The location of the camera (view location)
view_location = region_3d.view_location
# The rotation of the view (view rotation)
view_rotation = region_3d.view_rotation
# This is the pivot point in world space (directly from the view_location)
# No need for complex matrix calculations as we are already getting it directly.
return view_location
def modal(self, context, event):
# Detect when rotation starts
if event.type == 'MOUSEMOVE' and event.alt:
if not self.is_rotating:
self.is_rotating = True
# Calculate and print the rotation point once (in world space)
self.rotation_pivot = self.get_rotation_pivot_world(context)
print(f"Viewport Rotation Started. Pivot Point: {self.rotation_pivot}")
# Detect when rotation stops (mouse release or ESC)
elif self.is_rotating and event.type in {'LEFTMOUSE', 'RIGHTMOUSE', 'ESC'}:
self.is_rotating = False
print("Viewport Rotation Stopped.")
return {'PASS_THROUGH'}
def execute(self, context):
self.is_rotating = False
self.rotation_pivot = None # Reset the pivot point when starting the operator
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
self.is_rotating = False
self.rotation_pivot = None
print("Stopped tracking viewport rotation.")
def menu_func(self, context):
self.layout.operator(ViewportRotationPointDebugger.bl_idname)
def register():
bpy.utils.register_class(ViewportRotationPointDebugger)
bpy.types.VIEW3D_MT_view.append(menu_func)
def unregister():
bpy.utils.unregister_class(ViewportRotationPointDebugger)
bpy.types.VIEW3D_MT_view.remove(menu_func)
if __name__ == "__main__":
register()
Unfortunately it will work correctly only in case we select some object and focus the camera on it. But if we pan view somewhere a bit, we would get incorrect values.