Way to track the viewport point of view?

For the purposes of “doing something based on camera distance”, can I track a position of the “camera” which isnt present as scene object (one which is used to navigate the scene)?

Yeah, you can track the position of anything:

bpy.data.objects[“something”].location 

For the camera that exists as Object, it is trivial, yes. But is there a keyword to access a point of view which is used while you navigate the scene, outside Camera view?

Do you mean the viewport view? The easiest way is with the Stored Views add-on that comes with blender, that lets you add a camera to your current viewport view, or you can do it the hard way:

1 Like

view_matrix belongs to RegionView3d, and there is view_location as well. Likely, this is what I need, thanks

1 Like

Strange. Blender thinks this script is correct, but the dummy position doesnt update

import bpy
def ViewpointTracker(scene):
bpy.data.objects[“Empty”].location = bpy.context.region_data.view_location
bpy.app.handlers.depsgraph_update_post.append(ViewpointTracker)

I did mention that this was the hard way, right? :wink:
Navigating the viewport doesn’t count as a depsgraph_update. Changing objects or modes, using an operator, or editing data are the events that trigger that handler

This would make sense, only I’ve tried poking objects and the script did not respond either. Pytrhon auto exectution is turned on too

Are you getting any errors in the system console?
Another option: add a camera, parent the empty to the camera, turn Lock to View on, now your viewport navigation will update your empty location

1 Like

Sometimes it gives NoneType error on view_location, though not immediately at the start of the script. So I assumed it happens when 3d viewport window isnt active

Yeah, that tracks. I’m guessing you’re going to have to manually set the context. Give me an hour and I’ll play around with your code

No hurry; camera lock solution works for me, I am just curious what is wrong with the script

1 Like
  1. You’re not running your function?
  • Add this code line at the end of your script if you haven’t already:
if __name__ == "__main__":
    ViewpointTracker(bpy.context.scene)

2. Your script must be run as an operator, not in the Text Editor.

you’re ruining the script from the script editor and in this case the script editor has no ‘region_3d’.

  • His guide can be found here.
1 Like

Hmm.I got the point, but neither their SimpleOperator example nor my code processed accordingly shows up in operator search

Any errors? Could you share your new code.

You don’t need to run the function if it’s attached to an app handler, which it is

1 Like

SimpleOperator.py (547 Bytes)
ViewpointTracker.py (662 Bytes)
No errors for both the “SimpleOperator” example copy pasted from another thread, and for my script. Both fail to register as operators. Autorun is enabled for scripts BTW.

I’m not sure why it’s not working for you. If I include your bpy.data.objects["Empty"].location = bpy.context.region_data.view_location line from your ViewpointTracker.py script into your SimpleOperator.py script it works for me when I run it as an operator.

Video Proof

Script

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Operator"

    @classmethod
    def poll(cls, context):
        return bpy.context.area.type == "VIEW_3D"

    def execute(self, context):
        bpy.data.objects["Empty"].location = bpy.context.region_data.view_location
        return {'FINISHED'}

def register():
    bpy.utils.register_class(SimpleOperator)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()
2 Likes

Could it be that custom operators have to be enabled through some preference setting?

I’m not sure. The only setting I can think of would be this setting:

However, that shouldn’t be blocking your operator scripts from running if you’re running them manually.