- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望在 OSX 上获得高分辨率和高帧速率的鼠标移动。
“高帧率”= 60 fps 或更高(最好 > 120)
“高分辨率”=子像素值
问题
我有一个 opengl View 以大约显示器刷新率运行,因此约为 60 fps。我使用鼠标环顾四周,因此隐藏了鼠标光标并依赖于鼠标增量值。
问题是鼠标事件的帧速率太低,并且值被捕捉到整数(整个像素)。这会导致“不稳定”的观看体验。以下是鼠标增量值随时间变化的可视化:
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
这是一条典型的(缩短的)曲线,由用户将鼠标稍微向右移动而创建。每个 x 代表每个帧的 deltaX 值,并且由于 deltaX 值四舍五入为整数,因此该图实际上相当准确。正如我们所看到的,deltaX 值在一帧中将为 0.000,然后下一帧为 1.000,但随后它将再次为 0.000,然后为 2.000,然后再次为 0.000,然后为 3.000、0.000,依此类推。
这意味着 View 将在一帧中旋转 2.000 单位,然后在下一帧中旋转 0.000 单位,然后旋转 3.000 单位。当鼠标以或多或少恒定的速度拖动时会发生这种情况。不用说,这看起来很糟糕。
那么,我该如何 1) 提高鼠标的事件帧率? 2)获取子像素值?
到目前为止
我尝试过以下方法:
- (void)mouseMoved:(NSEvent *)theEvent {
CGFloat dx, dy;
dx = [theEvent deltaX];
dy = [theEvent deltaY];
// ...
actOnMouse(dx,dy);
}
嗯,这一点很明显。 dx
这里是 float ,但值总是四舍五入(0.000、1.000 等)。这将创建上面的图表。
所以我想下一步是在鼠标事件进入 WindowServer 之前尝试点击鼠标事件。所以我创建了一个 CGEventTrap:
eventMask = (1 << kCGEventMouseMoved);
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
0, eventMask, myCGEventCallback, NULL);
//...
myCGEventCallback(...){
double dx = CGEventGetDoubleValueField(event, kCGMouseEventDeltaX);
double dy = CGEventGetDoubleValueField(event, kCGMouseEventDeltaY);
}
仍然值为 n.000
,尽管我相信事件触发率要高一些。但它仍然没有达到 60 fps。我仍然得到上面的图表。
我还尝试过将鼠标灵敏度设置得非常高,然后在我这边缩小这些值。但似乎 OSX 增加了某种加速或其他东西——这些值变得非常“不稳定”,因此无法使用,而且射速仍然太低。
不幸的是,我开始追踪鼠标事件,最终到达了 IOKit。这对我来说很可怕。这是疯帽子。苹果文档变得很奇怪,似乎在说“如果你这么深入,你真正需要的只是头文件”。
所以我一直在阅读头文件。我还发现了一些有趣的花絮。
在 <IOKit/hidsystem/IOLLEvent.h>
第 377 行有这个结构:
struct { /* For mouse-down and mouse-up events */
UInt8 subx; /* sub-pixel position for x */
UInt8 suby; /* sub-pixel position for y */
// ...
} mouse;
看,它说的是子像素位置!好的。然后在<IOKit/hidsystem/IOLLParameter.h>
中的第73行
#define kIOHIDPointerResolutionKey "HIDPointerResolution"
嗯。
总而言之,我感觉 OSX 深入了解子像素鼠标坐标,并且必须有一种方法来读取每一帧的原始鼠标移动,但我只是不知道如何获取这些值.
问题
呃,那么,我在要求什么呢?
(抱歉,帖子太长)
最佳答案
(这是一个很晚的答案,但我认为对于其他偶然发现这一问题的人来说仍然有用。)
您是否尝试过过滤鼠标输入?这可能很棘手,因为过滤往往是滞后和精度之间的权衡。然而,几年前我写了一篇文章,解释了我如何过滤鼠标移动,并为游戏开发网站写了一篇文章。链接为http://www.flipcode.com/archives/Smooth_Mouse_Filtering.shtml .
由于该网站不再处于积极开发状态(并且可能会消失),因此以下是相关摘录:
<小时/>几乎在所有情况下,过滤都意味着平均。然而,如果我们简单地平均鼠标移动随时间的变化,我们就会引入滞后。那么,我们如何在不引入任何副作用的情况下进行过滤呢?好吧,我们仍然会使用平均,但我们会用一些智能来做到这一点。同时,我们将为用户提供对过滤的精细控制,以便他们可以自行调整。
我们将使用随时间变化的平均鼠标输入的非线性过滤器,其中旧值对过滤结果的影响较小。
它是如何工作的
每一帧,无论您是否移动鼠标,我们都会将当前鼠标移动放入历史缓冲区并删除最旧的历史值。因此,我们的历史记录始终包含 X 个样本,其中 X 是“历史缓冲区大小”,代表一段时间内最近采样的鼠标移动。
如果我们使用历史缓冲区大小 10 以及整个缓冲区的标准平均值,则过滤器会引入大量滞后。在 60FPS 的机器上,快速的鼠标移动将落后 1/6 秒。在快速 Action 游戏中,这会非常流畅,但实际上无法使用。在相同的场景中,历史缓冲区大小为 2 会给我们带来非常小的延迟,但过滤效果非常差(玩家 react 粗糙且不稳定。)
非线性滤波器旨在对抗这种互斥的情况。这个想法很简单。我们不是盲目地对历史缓冲区中的所有值进行平均,而是用权重对它们进行平均。我们从权重 1.0 开始。因此历史缓冲区中的第一个值(当前帧的鼠标输入)具有完整的权重。然后,我们将此权重乘以“权重修正值”(例如...0.2),然后移至历史缓冲区中的下一个值。我们走得越远(通过我们的历史缓冲区),这些值对最终结果的权重(影响)就越小。
详细来说,权重修改值为 0.5 时,当前帧的样本将具有 100% 的权重,前一个样本将具有 50% 的权重,下一个最旧的样本将具有 25% 的权重,下一个样本将具有 12.5% 的权重,很快。如果将其绘制成图表,它看起来像一条曲线。因此,权重修改器背后的想法是控制随着历史样本变老,曲线下降的急剧程度。
减少延迟意味着减少权重调节器。将权重调节器减少到 0 将为用户提供原始的、未经过滤的反馈。将其增加到 1.0 将使结果成为历史缓冲区中所有值的简单平均值。
我们将为用户提供两个用于精细控制的变量:历史缓冲区大小和权重修改器。我倾向于使用大小为 10 的历史缓冲区,然后使用权重修改器,直到我满意为止。
关于cocoa - OSX 上的高分辨率和高帧率鼠标坐标? (或者其他解决方案?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6791262/
我正在寻找一种方法来创建根据价格选择我的产品的过滤器(选择下拉菜单)。 我知道这样的查询是完全可能的: SELECT * FROM products ORDER BY price ASC SELECT
函数参数中或显示尺寸时(高度,宽度)的顺序是否有约定? 最佳答案 我不知道大量的语言,但我使用过的语言(宽度,高度)。它更适合沿着 (x, y) 坐标线。 关于language-agnostic -
在我的表单中,我让用户输入房间的长度高度和宽度以获得 m2、m3 和瓦特的计算值。但是用户也应该能够直接输入 height 和 m2 来获取值。我尝试了很多语法,但 if else 不能正常工作。我知
我在 Elasticsearch 中创建了一个索引,看起来像 {"amazingdocs":{"aliases":{},"mappings":{"properties":{"Adj Close":{"
我有以下功能,我需要清除数据库中的所有图片列并移动到文件系统。当我一次性完成这一切时,内存太多并且会崩溃。我切换到递归函数并执行 20 次写入和批量操作。 我需要为大约 6 个表执行此操作。我的 Re
我正在编写一个函数来计算 PI 的值,并将其作为 double 值返回。到目前为止,一切都很好。但是一旦函数到达小数点后14位,它就不能再保存了。我假设这是因为 double 有限。我应该怎么做才能继
2020年是中国CDN行业从98年诞生到今天快速发展的第二十四年,相关数据显示,全国感知网速持续上扬,达到了3.29兆/秒,标志着在宽带中国的政策指导下,中国的网速水平正在大步赶上世界发达国家的水平
在 aerospike 集合中,我们有四个 bin userId、adId、timestamp、eventype,主键是 userId:timestamp。在 userId 上创建二级索引以获取特定用
$('#container').highcharts('Map', { title : { text : 'Highmaps basic demo'
有没有办法显示自定义宽度/高度的YouTube视频? 最佳答案 在YouTube网站上的this link中: You can resize the player by editing the obj
我使用 Highcharts ,我想在 Highcharts 状态下悬停时制作动态不同的颜色。 正如你可以看到不同的颜色,这就是我做的 var usMapChart , data = [] ; va
在所有节点上运行 tpstats 后。我看到很多节点都有大量的 ALL TIME BLOCKED NTR。我们有一个 4 节点集群,NTR ALL TIME BLOCKED 的值为: 节点 1:239
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我已经 seen >2 字节的 unicode 代码点,如 U+10000 可以成对编写,如 \uD800\uDC00。它们似乎以半字节 d 开头,但我只注意到了这一点。 这个 split Actio
有人可以帮我理解为什么我的饼图百分比计算不正确吗?看截图: 根据我的计算,如 RHS 上所示,支出百分比应为 24.73%。传递给 Highcharts 的值如下:- 花费:204827099.36-
我阅读了有关该问题的所有答案,但我还没有找到任何解决方案。 我有一个应用程序,由我的 api 服务器提供。 Wildfly 8.1 和 Mysql 5.6。当查看时间到来时(Wildfly 服务器连接
我正在用选定的项目创建圆形导航。当用户单击任何项目时,它将移动到定义的特定点。一切都很好,除了当你继续点击项目时,当动画表现不同并且项目在 360 度圆中移动并且它被重置直到你重复场景时,我希望它
我是一名优秀的程序员,十分优秀!