Ralf_Reddings
Ralf_Reddings

Reputation: 1507

Advice on how I can go about writting this program?

For a long time, I have been going through THESE types of devices in hopes of getting a hardware interface that is pressure sensitive and also provides tactile feedback. The closest I have gotten was the space mouse by 3DConnextion. It was perfect, The input rate was proportional to how much pressure I was applying to the knob but its plagued with proprietary implementation, thus only a handful of software's support it.

But mostly importantly with all these devices, if I wanted the device to be driven by AHK code, I had to essentially turn them into dummy mouse/keyboard devices. Which would nullify their selling point (pressure sensitive/tactile feedback)

While using Autodesk Maya, I came across a solution. I realised the solution was all along right under my nose, my trusty mouse:

But how does a mouse act as an interface that is pressure sensitive and also provides tactile feedback?

By dragging the mouse either along X or Y axis:

HERE is a little demonstration of what I am talking about. Moving mouse left the animation goes back by 1 frame, moving mouse right the animation goes forward by 1 frame, as you can see, I can go very slow (frame by frame) to scrubbing extremely fast. I have a pretty good gaming mouse. The whole operation provides perfect tactile feedback, down to the pixel level.

So to implement the same feature found in Maya, in a 2D animation software:

The thing is am stuck on how I can actually go about implementing this in AutoHotkey as a general operation that can be bound to any key, It gets even more complicated because I want to also take advantage of both the X and Y axis.

Lets say for example, while the Space key is down held down, for every 10 pixels the mouse moves:

After an hour of mucking about, the following is what I have:

#singleinstance, force
#Persistent
#NoEnv
#Warn, All, OutputDebug
#MaxHotkeysPerInterval 500
SetBatchLines, -1

Return
~space::
CoordMode, Mouse, Screen
MouseGetPos, StartX, StartY
ToolTip, % "StartX: " StartX "`nStartY1: " Starty          ;Temporary, for Debugging
KeyWait, Space
Sleep, 500                                                 ;Temporary sleep command for diffrentiating "Start" and "current" Tooltip
MouseGetPos, CurrentX, CurrentY
ToolTip, % "CurrentX: " CurrentX "`nCurrentY: " CurrentY   ;Temporary, for Debugging

If(CurrentX > StartX)
    SendInput, {Right}

If(CurrentX < StartX)
    SendInput, {Left}

If(CurrentY > StartY)
    SendInput, {Up}

If(CurrentY < StartY)
    SendInput, {Down}

Return
Esc::ExitApp

Its not working code, I feel my AHK knowledge is being tested to its limit. I think I am stuck on establishing the core underlying mechanism, which seem to be at If(CurrentX < StartX) but I cant quite figure it out.

How do I for example routinely check if there is a difference of 10 pixels between StartX and CurrentX

Is it even necessary to check for such a difference? I would appreciate any input and examples of how I can go about this. Thank you.


EDIT 1: So after some more experimenting I came up with this, which sort of works:

#singleinstance, force
#Persistent
#NoEnv
#Warn, All, OutputDebug
#MaxHotkeysPerInterval 500
SetBatchLines, -1

Return
space::
CoordMode, Mouse, Screen
while GetKeyState("space", "p")
    {
    StartX := CurrentX
    StartY := CurrentY
    MouseGetPos, CurrentX, CurrentY
    
    Sleep, 555
    ToolTip, % "StartX: " StartX "`nStartY1: " StartY
    Sleep, 555
    If(CurrentX > StartX)
        ToolTip, CurrentX > StartX

    If(CurrentX < StartX)
        ToolTip, CurrentX < StartX

    If(CurrentY > StartY)
        ToolTip, CurrentY > StartY

    If(CurrentY < StartY)
    Tooltip, CurrentY < StartY
    }

Return
Esc::ExitApp

When I move 1 pixel to the Left, the message CurrentX < StartX is printed When I move 1 pixel to the Right, the message CurrentX > StartX is printed

When I move 1 pixel to the Up, the message CurrentY < StartY is printed When I move 1 pixel to the Down , the message CurrentY > StartY is printed

But its extremely error prone, as the threshold is only 1 pixel, attempting to move 1 pixel up can sometimes be taken as 1 pixel left.

Upvotes: 0

Views: 98

Answers (1)

Relax
Relax

Reputation: 10543

You can define a custom threshold (e.g 10 pixels) in the auto-execute section:

#NoEnv
#SingleInstance Force

threshold=10

CoordMode, Mouse, Screen

space::
    while GetKeyState("space", "p")
    {
        MouseGetPos, X1, Y1
        Sleep, 500
        MouseGetPos, X2, Y2
        
        If (X2 > X1+threshold)
            SendInput, {Right}
            
        If(X2 < X1-threshold)
            SendInput, {Left}

        If(Y2 > Y1+threshold)
            SendInput, {Down}

        If(Y2 < Y1-threshold)
            SendInput, {Up}             
    }
return

EDIT:

Try also this:

#NoEnv
#SingleInstance Force

threshold = 10

space::
    X1 := ""
    Y1 := ""
    while GetKeyState("space", "p")
    {
        X2 := X1
        Y2 := Y1
        MouseGetPos, X1, Y1
        dX := dX = "" ? X1 - X2 : dX + X1 - X2      
        dY := dY = "" ? Y1 - Y2 : dY + Y1 - Y2

        if (dX**2 >= threshold**2)
        {
            SendInput % (dX > 0 ? "{Right}" : "{Left}")
            dX -= threshold * ((dX > 0) * 2-1)
        }
        
        if  (dY**2 >= threshold**2)
        {
            SendInput % (dY > 0 ? "{Down}" : "{up}")
            dY -= threshold * ((dY > 0) * 2-1)
        }
    }
return

Upvotes: 1

Related Questions