Patas que ficam plantadas: IK de dois ossos em Molang para o Doggoyle
Como o Doggoyle do LLS Magic Pack mantém as patas no chão a passo, a trote e a galope: um relógio de passada a partir da velocidade no chão, pisadas planejadas no piso, e cinemática inversa resolvida em todo quadro no Molang do Bedrock.
A maioria das criaturas do Minecraft anda balançando as pernas para a frente e para trás numa onda senoidal. É barato e numa vaca fica bem, mas os pés deslizam: a perna balança numa velocidade, o corpo anda em outra, e as patas patinam no chão. Num cão de pedra grande e pesado, com patas compridas e com garras, essa patinação é a primeira coisa que se nota.
O Doggoyle, o cão de guarda dos hoggoyles no Magic Pack, faz ao contrário. Primeiro se planeja no chão onde cada pata vai, e a perna dobra para colocar ela lá. Isso é cinemática inversa, e no Bedrock ela precisa rodar em Molang, a linguagem de expressões do pacote de texturas, em todo quadro, no dispositivo do jogador.
Por que a perna precisa ser resolvida
Animar uma perna normalmente quer dizer definir ângulos nas articulações: tanto no ombro, tanto no cotovelo. A pata termina onde esses ângulos colocarem. A cinemática inversa inverte isso: você diz para onde a pata vai, e resolve os ângulos.
A pata dianteira e a traseira de um cachorro são, cada uma, dois ossos compridos com uma articulação no meio, que é o caso clássico de dois ossos:
- Pata dianteira: o ombro em cima, o cotovelo atrás dele, e o antebraço inclinado para a frente até o punho.
- Pata traseira: o quadril, a soldra para a frente, a tíbia para trás até o jarrete, e depois um metatarso quase vertical até a pata.
Com a raiz (ombro ou quadril), o alvo (punho ou jarrete) e o comprimento dos dois ossos, a dobra tem exatamente uma resposta de cada lado. Para que lado ela dobra é o que faz dela uma perna de cachorro e não de pássaro: cotovelos dobram para trás, soldras para a frente.
A resolução em si são duas funções de Molang: math.atan2 para a direção da raiz até o alvo, e
math.acos com a lei dos cossenos para quanto cada articulação dobra para cobrir a distância. O Molang
do Bedrock trabalha em graus, o que ajuda; a rotação do osso é então o ângulo de repouso, menos a
inclinação do pai, menos o ângulo resolvido. Quatro pernas, quatro resoluções, em todo quadro.
Passo 1: um relógio de passada que sabe a que velocidade está
Antes de planejar as pisadas você precisa saber em que ponto da passada o cachorro está. A entrada óbvia
é q.modified_distance_moved, o contador de balanço dos membros que as criaturas normais usam. Ele não
é em blocos: corre a mais ou menos quatro vezes a distância e tem limite. Uma passada medida por ele sai
errada em qualquer velocidade. (Esse está num texto anterior sobre bugs silenciosos do
Bedrock.)
Então o relógio do Doggoyle roda com q.ground_speed, a velocidade real sobre o chão, integrada numa
fase de passada. O contador é só um reserva. O andamento também vem da velocidade:
| Andamento | Padrão de pisadas |
|---|---|
| Passo | Quatro tempos: traseira esquerda, dianteira esquerda, traseira direita, dianteira direita, a um quarto de passada uma da outra |
| Trote | Pares na diagonal: traseira esquerda com dianteira direita, e depois o outro par meia passada mais tarde |
| Galope | O galope rotativo de um cachorro: traseira esquerda, traseira direita, dianteira direita, dianteira esquerda, em volta do corpo |
Mudar de andamento move cada perna para a frente no ciclo dela até o novo tempo, nunca para trás, então não tem perna tremendo para trás na troca de andamento.
Passo 2: planejar a pata no chão
Cada perna tem uma fase na passada. Parte da passada ela fica embaixo (o apoio), o resto fica em cima (o voo).
- Embaixo: a pata varre para trás em linha reta, exatamente na velocidade em que o chão anda embaixo do cachorro. A varredura é o comprimento da passada vezes a fração da passada em que a pata fica embaixo. Se isso bate, uma pata apoiada não se mexe em relação ao chão. É essa a ideia toda.
- Em cima: a pata vai para a frente numa curva de Hermite cujas velocidades em cada ponta batem com o apoio, então não tem tranco na saída nem no toque.
A pata também inclina: o calcanhar sobe no fim do apoio enquanto os dedos ficam embaixo, e volta no voo. Essas patas são compridas (as garras vão sete unidades à frente do punho), então uma pata dobrada precisa levantar o punho para passar pelo chão. Quanto levantar é calculado a partir da dobra, não chutado, mais uma folguinha.
Depois a IK pega os alvos do punho e do jarrete e dobra as pernas para alcançar.
Conferi fora do jogo com a mesma matemática que o Molang roda, em todo andamento: uma pata apoiada anda menos de 0,4 unidade durante um apoio.
O que deu errado, e como cada coisa foi pega
Cada uma destas foi achada por uma verificação numérica (uma quebra na curva de uma articulação, uma pata abaixo do chão) e não no olho. Ver uma animação em velocidade normal esconde muita coisa.
Um limite duro de alcance quebra o cotovelo
A galope total, o alvo de uma pata pode estar mais longe do que a perna alcança. A correção óbvia,
math.clamp na distância, trava o cotovelo totalmente reto e depois solta: um estalo visível no fim
de todo alcance.
A correção é um limite suave. A menos de uma unidade do alcance total, a distância vai freando de forma exponencial em vez de parar seco:
reach = d < dmax - 1 ? d : dmax - math.exp(dmax - 1 - d)
A perna estica suave e nunca chega a travar.
Uma pata que dobra demais, dobra duas vezes
Patas compridas têm uma propriedade chata: as pontas das garras ficam mais baixas por volta de 70 graus
de dobra. A primeira versão levantava o calcanhar, dobrava e erguia a pata em três curvas separadas
juntadas com max(), e a dobra passava dos 70 graus duas vezes por voo. Então o quanto o punho precisava
subir tinha duas corcovas, e o cotovelo dobrava duas vezes por passada.
Agora a flexão inteira da pata é uma corcova suave só, um cosseno elevado: começa quando o calcanhar sobe, chega ao máximo cedo no voo, e já achatou aos 85% do voo para a pata pousar reta. A dobra tem limite para nunca passar do ponto mais baixo.
Levante demais uma pata traseira e a coxa dá uma chicotada
A pata traseira dobra bem menos que a dianteira. Levantada tão alto quanto a da frente, ela colocava o jarrete bem do lado do quadril, e perto de uma linha reta passando pela raiz a resolução é hipersensível: a coxa girou 50 graus em dois quadros.
O balanço do corpo afunda as patas de um lado
Um cachorro trotando balança, o que abaixa um ombro e levanta o outro. Com uma altura de raiz só, compartilhada, as patas do lado baixo entravam no chão. Agora cada perna recebe a própria altura de raiz a partir do balanço, então o lado baixo dobra mais e o lado alto estica.
Ombros que balançam como porta
O primeiro modelo fazia o ombro numa peça só com o braço, uma placa até a cernelha. Cada passo balançava a placa inteira pelo corpo como um pêndulo. O ombro e a garupa agora são blocos fixos no corpo, com o membro encaixado dentro deles.
Misturando poses: misture onde a pata vai, não os ângulos
O Doggoyle pula, aterrissa, senta, deita e nada na água. O primeiro pulo misturava dois conjuntos de ângulos de articulação: a pose correndo e a pose no ar. Misturar ângulos produz uma perna mais comprida que as duas, então nos primeiros quadros de toda aterrissagem as patas entravam 1,4 unidade no chão.
Agora a mistura é de onde a pata vai, e a mesma IK resolve a perna em todo quadro a partir disso. A inclinação da pata funciona igual: cancela a rotação da cadeia inteira e depois soma uma inclinação misturada só, no mundo, então uma pata nunca passa pela posição de dedos para baixo enquanto está perto do chão.
Queixos atravessando o chão
Sentar, deitar e se enrolar foram posados na mão, e cada um ficava certo sozinho. Aí o corpo descia para deitar e o queixo atravessava o chão. As poses de repouso agora são resolvidas contra o chão (uma busca por bissecção da altura em que o queixo passa raspando), e tem um protetor de queixo em todo quadro: qualquer que seja a mistura de estados do cachorro, a altura do queixo é calculada a partir do corpo, e ela nunca fica abaixo do chão.
Tudo roda em Molang
Tudo isto fica nos scripts pre_animation da entidade do cliente, que rodam em todo quadro antes das
animações. O Molang tem funções com número fixo de argumentos (math.max aceita exatamente dois, e com
três quebra a entidade inteira calado) e para se você lê uma variável antes de definir, então a ordem das
linhas importa tanto quanto a matemática. O modelo, a animação e o Molang são gerados juntos por um script
só, que também roda as verificações acima antes de escrever qualquer coisa.
Conheça o Doggoyle nas masmorras de enxofre do Magic Pack. Dome um com uma maçã dourada normal; o guia do Magic Pack explica como achar uma masmorra.
O mod
Mais do devlog
- Cinco bugs de complementos do Bedrock que falham sem dar erro Um cavalo invisível, pernas correndo quatro vezes rápido demais, uma criatura que esqueceu como pular e um pacote de magia que quebrou sem ninguém mexer. Cinco bugs de complementos do Minecraft Bedrock que encontrei fazendo o LLS Equestrian e o Magic Pack, e como pegar cada um.
- Fazendo nevar numa fazenda de planície: fingindo clima de inverno no Minecraft Bedrock O Bedrock não tem clima de neve e decide entre chuva e neve pelo bioma. Como o LLS Seasons monta um dia de neve com neblina, uma partícula e uma camada de neve própria, e o congelamento de verão que uma varredura de neve causou.
- Como fazer uma porteira girar no Minecraft Bedrock, quando blocos não podem ser animados Os blocos do Bedrock não se mexem, e a colisão de um bloco personalizado precisa caber dentro de um bloco. Como as porteiras duplas do LLS Missing Blocks fingem as duas coisas, e os truques de colisão que seguram uma vaca e deixam um cavalo passar.