Desenvolvo um software que converte a entrada de movimento em uma resposta precisa e precisa do mouse, além de manter um site que tenta ajudar os desenvolvedores a implementar soluções igualmente boas. Eu geralmente desaconselho os limiares de movimento, embora dependa da capacidade de resposta e precisão que os jogadores desejam, fico feliz que esteja trabalhando para você em sua situação. Mas aqui vou oferecer uma solução diferente:
Eu uso algo chamado Smooth Tiered Smoothing . A idéia é que desviaremos a entrada por meio de diferentes algoritmos de suavização, dependendo da magnitude atual da velocidade do giroscópio (na prática, um desses algoritmos de suavização é simplesmente "sem suavização"). Essa é a parte "em camadas". A parte "flexível" é que podemos realmente dividir suavemente a entrada entre diferentes algoritmos de suavização, dependendo de como ela se compara a 2 limites.
Ele preserva o deslocamento corretamente e não adiciona nenhum atraso aos movimentos rápidos.
Na prática, você tem dois limites. Quando a magnitude da velocidade de entrada é menor que o limite mais baixo, estamos usando um algoritmo de suavização simples (média em vários quadros). Quando é maior que o outro limite, não usamos nenhum algoritmo de suavização. Mas, neste caso, ainda estamos passando zeros para o algoritmo de suavização de limite inferior.
Quando a velocidade de entrada está entre os dois limites, dividimos a entrada entre os dois algoritmos de acordo.
Aqui está um trecho do artigo acima:
GetSoftTieredSmoothedInput(Vec2 input, float threshold1, float threshold2) {
// this will be length(input) for vectors
float inputMagnitude = Abs(input);
float directWeight = (inputMagnitude - threshold1) / (threshold2 - threshold1);
directWeight = clamp(directWeight, 0, 1);
return GetDirectInput(input * directWeight) +
GetSmoothedInput(input * (1.0 - directWeight));
}
GetDirectInput apenas retorna o que é dado a ele, mas é para mostrar que outro algoritmo de suavização pode ser usado aqui. GetSmoothedInput pega uma velocidade e retorna uma velocidade suavizada.
Com Suavização em camadas suaves, não há suavização aplicada a movimentos obviamente intencionais (acima do limite maior), há suavização aplicada para encobrir pequenas quantidades de tremulação, o que também afetará movimentos muito pequenos, mas quando você atinge seus limites corretamente, não é muito perceptível. E há uma transição muito suave entre os dois (sem a qual, o jitter pode realmente ser amplificado).
Enquanto as outras respostas têm razão em dizer que é difícil reconhecer a instabilidade no instante em que uma entrada é recebida, também é verdade que a instabilidade é quase sempre uma velocidade muito baixa, e o atraso na entrada que vem com a suavização é muito menos perceptível nas entradas de baixa velocidade .
Como o artigo menciona, isso é usado em alguns lugares da minha ferramenta de código aberto JoyShockMapper , um mapeador de entrada que transforma a entrada de giroscópio em entrada de mouse. Mesmo para pessoas que usam outras ferramentas de remapeamento, como Steam ou reWASD, algumas usam o JoyShockMapper ao mesmo tempo apenas para seus controles de giroscópio.
Esta resposta assume que a entrada é dada em velocidade angular (que é comum em controladores que possuem controles de movimento), e não em orientação absoluta (que parece que o Razer Hydra está fornecendo a você). Com orientação absoluta, minha esperança é que você possa usar a diferença entre a orientação atual e a orientação relatada anteriormente para obter uma velocidade, mas não sei ao certo se funcionará tão bem quanto com os controladores que relatam a velocidade angular .
Uma solução de suavização comum quando você está lidando com uma posição / orientação absoluta, em vez de velocidades, é interpolar para a orientação da meta ao longo do tempo - isso é descrito em detalhes muito úteis neste artigo do Gamasutra. Isso também pode funcionar com suavização em camadas suaves. Você calculará a magnitude da velocidade usando a diferença entre esta entrada e a entrada relatada anteriormente. Você aplicará a diferença de orientação entre esse quadro e o último quadro multiplicado pelo valor "directWeight", conforme calculado no snippet acima. A última etapa é adicionar a entrada suavizada, mas devido à maneira como a suavização da orientação interpolada funciona, basta aplicar a alteração da orientação interpolada conforme o normal - ela não precisa considerar "directWeight". Apenas defina a orientação do alvo (é para isso que você está interpolando com a suavização descrita nesse artigo do Gamasutra) para qualquer orientação que estiver recebendo do dispositivo e interpole a orientação para ele, conforme descrito no artigo.