Me gustaría obtener movimientos del mouse en alta resolución y un alto framerate en OSX.¿Coordenadas de mouse de alta resolución y alto framerate en OSX? (¿O alguna otra solución?)
"alta tasa de fotogramas" = 60 fps o más (preferentemente> 120)
"alta resolución" valora = subpíxeles
Problema
Tengo una vista OpenGL funcionando aproximadamente a la tasa de refresco del monitor , entonces es ~ 60 fps. Uso el mouse para mirar alrededor, así que he ocultado el cursor del mouse y estoy confiando en los valores delta del mouse.
El problema es que los eventos del mouse vienen a una velocidad de fotogramas demasiado baja, y los valores se ajustan al entero (píxeles enteros). Esto causa una experiencia de visualización "entrecortada". Aquí es una visualización de valores delta de ratón con el tiempo:
mouse delta X
^ xx
2 | x x x x xx
| x x x x xx x x x
0 |x-x-x--xx-x-x-xx--x-x----x-xx-x-----> frame
|
-2 |
v
Esta es una curva típica (abreviado) creado a partir de que el usuario mueve el ratón un poco a la derecha. Cada x representa el valor deltaX para cada cuadro, y como los valores de deltaX se redondean a números enteros, este gráfico es realmente bastante preciso. Como podemos ver, el valor deltaX será 0.000 un cuadro, y luego 1.000 el siguiente, pero luego será 0.000 nuevamente, y luego 2.000, y luego 0.000 nuevamente, luego 3.000, 0.000, y así sucesivamente.
Esto significa que la vista rotará 2.000 unidades de un cuadro, y luego girará 0.000 unidades al siguiente, y luego girará 3.000 unidades. Esto ocurre mientras el mouse se está arrastrando con una velocidad más o menos constante. No hace falta decir que esto parece una mierda.
Entonces, ¿cómo puedo 1) aumentar la velocidad de fotogramas del evento del mouse? y 2) obtener valores de subpixel?
Hasta ahora
He intentado lo siguiente:
- (void)mouseMoved:(NSEvent *)theEvent {
CGFloat dx, dy;
dx = [theEvent deltaX];
dy = [theEvent deltaY];
// ...
actOnMouse(dx,dy);
}
Bueno, éste era obvio. dx
aquí es flotante, pero los valores son siempre redondeados (0.000, 1.000 etc.). Esto crea el gráfico de arriba.
Así que el siguiente paso fue tratar de tocar los eventos del mouse antes de que ingresen al WindowServer, pensé. Así que he creado un CGEventTrap:
eventMask = (1 << kCGEventMouseMoved);
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
0, eventMask, myCGEventCallback, NULL);
//...
myCGEventCallback(...){
double dx = CGEventGetDoubleValueField(event, kCGMouseEventDeltaX);
double dy = CGEventGetDoubleValueField(event, kCGMouseEventDeltaY);
}
Todavía valores son n.000
, aunque creo que la tasa de liberación evento es un poco más alto. Pero todavía no es a 60 fps. Todavía obtengo el cuadro de arriba.
También intenté establecer la sensibilidad del mouse realmente alta, y luego reducir los valores de mi lado. Pero parece que OSX agrega algún tipo de aceleración o algo así: los valores se vuelven realmente "inestables" y, en consecuencia, inutilizables, y la velocidad de disparo es aún demasiado baja.
Sin suerte, he comenzado a seguir los eventos del ratón por el agujero del conejo, y he llegado a IOKit. Esto es aterrador para mi Es el sombrerero loco. La documentación de Apple se vuelve rara y parece decir "si estás en el fondo, todo lo que realmente necesitas son archivos de encabezado".
He estado leyendo archivos de encabezado. Y he encontrado algunas cositas interesantes.
En <IOKit/hidsystem/IOLLEvent.h>
en la línea 377 está esta estructura:
struct { /* For mouse-down and mouse-up events */
UInt8 subx; /* sub-pixel position for x */
UInt8 suby; /* sub-pixel position for y */
// ...
} mouse;
Sede, que dice posición de sub-píxel! De acuerdo. A continuación, en la línea 73 en <IOKit/hidsystem/IOLLParameter.h>
#define kIOHIDPointerResolutionKey "HIDPointerResolution"
Hmm.
En general, tengo la sensación de que OSX sabe sobre las coordenadas del mouse sub-pixel en el fondo, y simplemente tiene que haber una manera de leer los movimientos crudos del mouse cada fotograma, pero no tengo idea de cómo obtenerlos valores.
Preguntas
Erh, entonces, ¿qué estoy pidiendo?
- ¿Hay alguna manera de obtener eventos de mouse de alta velocidad en OSX? (Código de ejemplo?)
- ¿Hay alguna manera de obtener coordenadas de mouse sub-pixel en OSX? (¿Código de ejemplo?)
- ¿Hay alguna manera de leer los deltas de mouse "en bruto" en cada cuadro? (Ie no confíe en un evento.)
- O, ¿cómo obtengo NXEvents o configuro HIDParameters? Código de ejemplo? (Para que pueda profundizar en esto por mi cuenta ...)
(Lo siento por largo post)