Especificações de comunicação do iFacialMocap


O iFacialMocap permite que desenvolvedores de ferramentas de terceiros recebam dados faciais usando UDP ou TCP/IP sem passar pelo software de PC.

Para receber dados via UDP

Se você enviar a string "iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719" do PC para a porta 49983 no lado iOS, o iFacialMocap retornará uma resposta via UDP para a porta 49983 a 60 FPS.

・ Exemplo em Python

from socket import *
DstIP = "192.168.1.7"
DstPort = 49983
DstAddr = (DstIP,DstPort)
udpClntSock = socket(AF_INET, SOCK_DGRAM)
data = "iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719"
data = data.encode('utf-8')
udpClntSock.sendto(data,DstAddr)

server = socket(AF_INET, SOCK_DGRAM)
server.bind(("", 49983))
server.settimeout(0.05)

while True:
    try:
        messages, address = server.recvfrom(8192)
        print(messages.decode('utf-8'))
    except:
        pass

・ A string enviada por quadro é a seguinte.

mouthSmile_R-0(eyeLookOut_L-0)mouthUpperUp_L-11(eyeWide_R-0)mouthClose-8|mouthPucker-4|mouthRollLower-9|eyeBlink_R-7|eyeLookDown_L-1|?cheekSquint_R-11|eyeBlink_L-7|tongueOut-0|jawRight-0|eyeLookIn_R-9|cheekSquint_L-11|mouthDimple_L-10|mouthPress_L-4|eyeSquint_L-11|mouthRight-0|mouthShrugLower-0|eyeLookUp_R-0|eyeLookOut_R-0|mouthPress_R-5|cheekPuff-2|jawForward-1|1|mouthLowerDown_L-9|mouthFrown_L-6|mouthShrugUpper-26|browOuterUp_L-4|browInnerUp-20|mouthDimple_R-10|browDown_R-0|mouthUpperUp_R-10|mouthRollUpper-8|mouthFunnel-12|mouthStretch_R-21|mouthFrown_R-13|eyeLookDown_R-17|jawOpen-12|jawLeft-0|browDown_L-0|mouthSmile_L-0|noseSneer_R-18|mouthLowerDown_R-8|noseSneer_L-21|eyeWide_L-0|mouthStretch_L-21|browOuterUp_R-4|eyeLookIn_L-4|eyeSquint_R-11|eyeLookUp_L-0|mouthLeft-0|=head#-21.488958,-6.038993,-6.6019735,-0.030653415,-0.10287084,-0.6584072|rightEye#6.0297494,2.4403017,0.25649446|leftEye#6.034903,-1.6660284,-0.17520553|34903,-1.6660284,-0.17520553|

・ As strings enviadas por quadro são as seguintes.

BlendShape Name-Parameter (0 ~ 100) | … | BlendShape Name-Parameter (0 ~ 100) | … | = head # Euler angles X (degree), Euler angles Y, Euler angles Z, Position values X, Position values Y, Position values Z | rightEye # Euler angles X, Euler angles Y, Euler angles Z | leftEye # Euler angles X, Euler angles Y, Euler angles Z |

Dados relacionados a ângulos são enviados em graus, não em radianos.

Desde o iOS ver. 1.1.8, foi adicionado um comando externo para compatibilidade com Facemotion 3d.
Se você adicionar a string "|sendDataVersion=v2" como mostrado abaixo, os valores do parâmetro BlendShape enviados serão separados por "&".
iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719|sendDataVersion=v2

[Exemplo]
Normal
mouthSmile_R-0
sendDataVersion = v2
mouthSmile_R & 0

A razão é que o Facemotion 3d pode enviar um valor negativo para o valor de blendShape.
Isso evita uma possível colisão ao usar "-" como delimitador.

Para receber dados via TCP/IP

Com UDP, quadros podem ser perdidos; por isso também existe um método de recebimento via TCP/IP.
Se você enviar por UDP a string "iFacialMocap_UDPTCP_sahuasouryya9218sauhuiayeta91555dy3719" para a porta 49983 no lado iOS, os dados serão enviados para a porta 49986 no lado PC.

A string a enviar é simplesmente a string "___iFacialMocap" adicionada à string enviada via UDP.

- exemplo
BlendShape Name-Parameter (0 ~ 100) | BlendShape Name-Parameter (0 ~ 100) | … | = head # Euler angles X, Euler angles Y, Euler angles Z, moving values X, moving values Y, moving values Z | rightEye # Euler angles X, Euler angles Y, Euler angles Z | leftEye # Euler angles X, Euler angles Y, Euler angles Z | ___iFacialMocap

Ao receber do iOS para o PC por TCP/IP, pode ser enviada uma string com frames divididos; use "___iFacialMocap" no final como delimitador.

Para interromper o envio por TCP/IP, envie a string "iFacialMocap_UDPTCPSTOP_sahuasouryya9218sauhuiayeta91555dy3719" para a porta 49983.

・ Exemplo de uso em Python recebido via TCP/IP

from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM

#UDP send
HOST = ''
PORT = 49983
ADDRESS = "192.168.1.7" #iOS address

s = socket(AF_INET, SOCK_DGRAM)
msg = "iFacialMocap_UDPTCP_sahuasouryya9218sauhuiayeta91555dy3719"
s.sendto(msg.encode(), (ADDRESS, PORT))

s.close()

#create tcp server
with socket(AF_INET, SOCK_STREAM) as tcp_server:
    tcp_server.bind(("192.168.1.5", 49986)) #192.168.1.5 is pc address
    tcp_server.listen(1)

    while True:
        conn, addr = tcp_server.accept()
        with conn:
            while True:
                data = conn.recv(10000)
                print(data.decode('utf-8'))

Desde o iOS ver. 1.1.8, foi adicionado um comando externo para compatibilidade com Facemotion 3d.
Se você adicionar a string "|sendDataVersion=v2" como mostrado abaixo, os valores do parâmetro BlendShape enviados serão separados por "&".
iFacialMocap_UDPTCP_sahuasouryya9218sauhuiayeta91555dy3719|sendDataVersion=v2

[Exemplo]
Normal
mouthSmile_R-0
sendDataVersion = v2
mouthSmile_R & 0

A razão é que o Facemotion 3d pode enviar um valor negativo para o valor de blend shape, e usar "-" como delimitador poderia causar colisão.

Para receber dados via Bluetooth

Se conexões de rede por Wi‑Fi, como UDP ou TCP/IP, falharem, você também pode usar Bluetooth como alternativa. Consulte o código do GitHub abaixo.

https://github.com/emoto-yasushi/iFacialMocap_Facemotion3d_Bluetooth

Para receber dados gravados no iOS

Se você enviar a string "iFacialMocap_bakeRecordedAnimation_start" para a porta 49983 no lado iOS via UDP, os dados gravados serão enviados para a porta 49987 no PC via TCP/IP.

A string enviada tem o formato [".....", ".....", "....."] ___iFacialMocap.
A parte [".....", ".....", "....."] está em formato JSON e armazena as mesmas strings usadas em UDP e TCP/IP.

Dados gravados a 60 FPS são sempre armazenados. (Mesmo que o processamento caia para 30 FPS no iOS, será gravado a 60 FPS.)

Esse não era o objetivo original do iFacialMocap, mas desenvolvedores de terceiros podem usá-lo livremente. No futuro, o desenvolvimento migrará gradualmente para um app sucessor; o iFacialMocap em si não será descontinuado. Se você usa esse recurso, observe que o tratamento dele pode mudar no app sucessor.

Executar o botão lookForward

Envie a string "iFacialMocap_lookForward" para a porta iOS 49983.

Streaming direto para Unity

Os scripts a seguir podem ser usados anexando-os a objetos do jogo.
Ele pode fazer streaming com iFacialMocap e Facemotion3d.
https://drive.google.com/file/d/10cnZRlglrHmZIv-ECT66eqNZNsiWhMtf/view?usp=sharing

Funciona especificando o nome do objeto conforme mostrado na imagem a seguir.

Unity Inspector for the iFacialMocap streaming script

Este script é destinado a arquivos FBX, não VRM.
Se quiser usar isso em VRM, crie sua própria versão ou envie-me um e-mail.