Object Mouse Input



  • On 17/06/2013 at 02:35, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R14 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi Folks,

    is it at all possible to retrieve the mouse coords and/or input with an objectdata plugin? Is there a flag that can be listened out for (haven't found one) in the Message() function that I could utilise? Something else I may not know/have overlooked?

    I'm trying to avoid using a scenehook plugin. I'm only needing it if the object is selected.

    WP.



  • 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)).



  • 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.



  • 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.



  • 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



  • 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.



  • 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



  • 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.



  • 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.



  • 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



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

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

    WP.


Log in to reply