Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Object Mouse Input

    SDK Help
    0
    11
    914
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 17/06/2013 at 03:22, xxxxxxxx wrote:

      No.  I think that you are stuck with a SceneHook plugin.  You can use the SceneHook to get the active document, get the selected object (doc->GetActiveObject()) and check to see if it is yours (op->IsInstanceOf(YOUR_PLUGIN_ID)).

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 17/06/2013 at 03:23, xxxxxxxx wrote:

        You can always call GetInputState in c4d_gui. The BFM_INPUT container also does include the current mouse coords.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 17/06/2013 at 03:51, xxxxxxxx wrote:

          Robert - I did initially have a SH plugin and was testing for op->GetType()==MyPluginID, but I don't particularly like the idea of the SH sitting in the background all the time. Though I may have to suffice with it.

          LD - do you mean testing if(GetInputState(blah)) inside the Draw() function?

          WP.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 17/06/2013 at 05:17, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            Robert - I did initially have a SH plugin and was testing for op->GetType()==MyPluginID, but I don't particularly like the idea of the SH sitting in the background all the time. Though I may have to suffice with it.

            LD - do you mean testing if(GetInputState(blah)) inside the Draw() function?

            WP.

            GetState() does only return if polling the asked channel has been successful, so directly 
            testing it does not make much sense, as the result does not reflect the result of the testing. 
            Simply  poll the current mouse state in the method of your choice and then proceed as you 
            wish. A little python script example(there is no difference for the general approach for cpp) :

            import c4d
            from c4d import gui
            #Welcome to the world of Python
              
            def main() :
                bc = c4d.BaseContainer()
                if gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, bc) :
                    gui.MessageDialog('Cursor is at x:{0}, y:{1}'.format(bc[c4d.BFM_INPUT_X],
                                                                         bc[c4d.BFM_INPUT_Y]))
                
            if __name__=='__main__':
                main()
            

            Maybe I did not understand correctly what you want to do.

            Happy rendering,
            Ferdinand

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 17/06/2013 at 05:56, xxxxxxxx wrote:

              The gist of what I'm trying to do is get the mouse's state in the viewport while my object is selected (it's position and it's button state). Basically wanting to emulate somehow what a scenehook could do, from inside an object plugin. But not having much luck with it. So might just have to revert back to a scenehook.

              Maybe I can use a very basic scenehook and just pass the values over to my object instead. Was really wanting to avoid using a SH though. Just makes another thing you have to go program for the sake of two numbers and a button's state.

              Thanks all,

              WP.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 17/06/2013 at 10:45, xxxxxxxx wrote:

                Howdy,

                You will need to use a Scene Hook if you want the mx, my coordinates to be relative to the editor viewport.

                This code:

                BaseContainer state;
                GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, state);
                Real mx = state.GetReal(BFM_INPUT_X);
                Real my = state.GetReal(BFM_INPUT_Y);
                GePrint("Cursor coordinates: x = "+RealToString(mx)+"; y = "+RealToString(my));
                

                ... can be used anywhere in any code at any time, but it gives you global screen coordinates.

                Adios,
                Cactus Dan

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 17/06/2013 at 11:10, xxxxxxxx wrote:

                  Hi Dan,

                  thanks for that. I've used similar code elsewhere, but in this particular circumstance I had an if statement that was holding it up (I had been trying to call it from the Draw() function). It works (though always returns values of 0) but I don't think I'm going to be able to poll it properly like a SH from the Draw().

                  I don't suppose there's a mouse-over-viewport message somewhere I could take advantage of is there?

                  WP.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 25/06/2013 at 12:16, xxxxxxxx wrote:

                    Hi all,

                    just a further query to this one, I'm using GetInputState with BFM_INPUT_MOUSELEFT & RIGHT inside if statements, but whichever one I run first seems to cancel out the other:

                      
                    if(GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, MB))   
                    {   
                        // whatever here for left mouse button   
                    }   
                    // but this if statement won't run   
                    if(GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSERIGHT, MB))   
                    {   
                        // whatever here for right mouse button.   
                    }   
                    

                    If I swap them around, then the left one won't run. Why is this?

                    WP.

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 25/06/2013 at 13:36, xxxxxxxx wrote:

                      Your if()'s don't have any conditions in them to run when the mouse buttons are no longer pressed.
                      That's why you get stuck in the first one.

                      The C4D SDK does not have a mouse up event. We have to do it manually.
                      So for mouse downs we have to use a while loop to get out of it when the user stops pressing the MB.

                      Example:

                      LONG myDialog::Message(const BaseContainer &msg, BaseContainer &result)  
                      {  
                        //The container where GetInputState() will store it's values  
                        BaseContainer state;  
                        
                        while (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, state)) //While the LMB is down   
                        {  
                          //If the state value == 0. The LMB is no longer down  
                          //So break out of this loop  
                          if (state.GetLong(BFM_INPUT_VALUE) == 0) break;  
                        
                          //If the state == 1 the MB is being held down     
                          if (state.GetLong(BFM_INPUT_VALUE) == 1)  
                          {  
                        //do something  
                        break;            //<---Use this break if you only want to execute the task once while LMB is held down  
                          }  
                        }  
                        
                        return GeDialog::Message(msg,result);  
                      }
                      

                      -ScottA

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 26/06/2013 at 01:05, xxxxxxxx wrote:

                        Ah, I see, thanks Scott. Makes sense. Working now.

                        WP.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post