Registering controller's events from within C4D



  • Hi!
    Let me say clearly - if not to mention a humble Python script development, I'm a noob.
    I stumbled upon quite a challenge for myself - I need to develop a custom controller software with a pretty easy concept - my plugin gets an info about an event from the controller and changes the view (pan, zoom, rotate) according to it's action. Something resembling SpaceNavigator.
    Things go on Mac OS

    And there's a lot of questions:

    1. I wanted to go an easy way - Swift program listening to controller and piping signals to Python C4D plugin. But... I realized I have no idea how they even could talk to each other and is there a way.
      The general approach is pretty unclear;

    2. Functions. I could not find how to call and guide Pan/Zoom/Rotate functions in the viewport in C++ SDK. At all. Console, not surprisingly, knows nothing about them.

    3. The simplest and stupidest way - to simulate mouse buttons over the viewport (not yet sure is it possible in Swift). Very stupid, really, but seems the most realistic. But if so, is there a way to get a viewport dimensions form C4D from another app, to trigger those action over the viewport only?

    I feel myself pretty impudent asking for all those ready-made recipes, but it's a rough start you know)
    So I'll be grateful for any hints and info ☺



  • Congrats, you managed to find one of the most challenging things possible in C4D. 😀

    I have written the alternative SpaceNavigator controller CollieMouse for C4D (Windows...) so I was faced with similar issues.

    First, C4D does not give you access to the message queue of the OS (or any proper windows functionality). C4D provides an abstraction layer for all GUI functionality so it will work on both Windows and MacOS, but it does not lay open sufficient functions for window control, much less internal OS stuff. I had to link to the Windows API itself, then open my own invisible window to process messages from the SpaceNavigator driver, all in its own thread to prevent deadlocks and busy waits. This ended up very OS dependent.

    The issue in communicating with external devices is that you need a listener within C4D, no matter what kind of events you pipe. A listener means you need to access some message queue which waits for events in a non-blocking way. Usually, under Windows you use the standard windows messaging system. I suppose there are other ways, esp. on MacOS. As I have no experience in this OS, I need to leave it to you to look for a proper cross-application queueing approach. C4D does not have any such system and hides the actual OS GUI windows and their messaging system from you.

    Second, there are no direct Pan/Zoom/Rotate functions. The position of the camera is controlled by its matrix. Moving the camera means you change the matrix appropriately. (For a scene camera, you will need to take into account that it may be part of a hierarchy with inherited position/rotation through the parent objects.)

    But beware! There are different views which need to be handled all on their own - Perspective, Parallel, Axonometric... The behavior of the camera depends on the selected view. Furthermore, there are scene cameras and viewport cameras (internally the same data structure but you need to know what camera you are working with); then there is the pivot that is needed for rotations (which by the way is still not supported by the built-in space mouse controller). I suppose you will not want to support all these details.

    Third, I'm not sure what you mean here... a GUI simulator that sends OS messages to the application, like in webapp testing? Imitating mouse input? This is certainly possible, although I'm not sure about the effectivity. C4D can check the viewport size and position, but as for how to send this to another application, you will again need to look for OS level messaging.

    Anyway, this first thing to look for is definitely a way to send and receive messages across applications, whether it be the windows system or some other library. (If anybody reading this has experience in novel ideas, I'll be happy to hear them.)



  • Hi @intendito, first of all welcome in the plugincafe community.

    Unfortunately, as @cairyn said, there is no direct and easy way for doing this in Cinema 4D.
    Regarding your first question, this is something very general, but you can take a look for shared memory or socket. For a more possible solution, see What is the preferred way of passing data between two applications on the same system?.

    Finally, I would like to point you to the CameraObject Manual and the BaseDraw Manual while they will not help you that much, it's still all we have regarding this topic.

    So wi will leave this topic to the community, but if you have a specific Cinema 4D SDK related question, please do not hesitate and ask it.

    Cheers,
    Maxime.



  • Sorry for late reply, there was an issue with my account.
    Many thanks for comprehensive answers. The topic looks kind of mind bending now, not much easier than after I realised Api doesn't really have what I expected to have for the task accomplishment 😓
    Now I think the better way might be to simulate the mouse over the viewport, so it will be an independent app which will only need from the Cinema to know where the viewport is. That seems easier I hope.
    When my research or development will reach some success I will share what I learned here, maybe it will be handy for somebody else.
    Thanks once more!