public void MessageDaisyChain(ref uOSC.Message message, int callCount)
        {
            //Startされていない場合無視
            if (externalReceiverManager == null || enabled == false || gameObject.activeInHierarchy == false)
            {
                return;
            }

            if (shutdown)
            {
                return;
            }

            StatusMessage = "OK";

            //異常を検出して動作停止
            try
            {
                ProcessMessage(ref message);
            }
            catch (Exception e)
            {
                StatusMessage = "Error: Exception";
                Debug.LogError(" --- Communication Error ---");
                Debug.LogError(e.ToString());
                shutdown = true;
                return;
            }

            if (!externalReceiverManager.SendNextReceivers(message, callCount))
            {
                StatusMessage = "Infinite loop detected!";
                shutdown      = true;
            }
        }
Exemplo n.º 2
0
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //カメラ姿勢FOV同期 v2.1
            if (message.address == "/VMC/Ext/Cam" &&
                (message.values[0] is string) &&
                (message.values[1] is float) &&
                (message.values[2] is float) &&
                (message.values[3] is float) &&
                (message.values[4] is float) &&
                (message.values[5] is float) &&
                (message.values[6] is float) &&
                (message.values[7] is float) &&
                (message.values[8] is float)
                )
            {
                cameraPos.x = (float)message.values[1];
                cameraPos.y = (float)message.values[2];
                cameraPos.z = (float)message.values[3];
                cameraRot.x = (float)message.values[4];
                cameraRot.y = (float)message.values[5];
                cameraRot.z = (float)message.values[6];
                cameraRot.w = (float)message.values[7];
                fov         = (float)message.values[8];
                //受信と更新のタイミングは切り離した
            }
        }
        void OnDataReceived(uOSC.Message message)
        {
            if (message.address != "/uNvPipe/Data")
            {
                return;
            }

            var buf       = (byte[])message.values[0];
            var pinnedBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
            var ptr       = pinnedBuf.AddrOfPinnedObject();

            decoder.Decode(ptr, buf.Length);
            pinnedBuf.Free();
        }
Exemplo n.º 4
0
        //デイジーチェーン処理
        public void MessageDaisyChain(ref uOSC.Message message, int callCount)
        {
            //Startされていない場合無視
            if (externalReceiverManager == null || enabled == false || gameObject.activeInHierarchy == false)
            {
                return;
            }

            //エラー・無限ループ時は処理をしない
            if (shutdown)
            {
                return;
            }

            //パケットリミッターが有効な場合、一定以上のパケットフレーム/フレーム数を観測した場合、次のフレームまでパケットを捨てる
            if (PacktLimiter && (LastPacketframeCounterInFrame > PACKET_LIMIT_MAX))
            {
                DropPackets++;
                return;
            }

            //メッセージを処理
            if (!Freeze)
            {
                //異常を検出して動作停止
                try
                {
                    ProcessMessage(ref message);
                }
                catch (Exception e) {
                    StatusMessage = "Error: Exception";
                    Debug.LogError(" --- Communication Error ---");
                    Debug.LogError(e.ToString());
                    shutdown = true;
                    return;
                }
            }

            //次のデイジーチェーンへ伝える
            if (!externalReceiverManager.SendNextReceivers(message, callCount))
            {
                //無限ループ対策
                StatusMessage = "Infinite loop detected!";

                //以降の処理を全部停止
                shutdown = true;
            }
        }
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //ライト同期 v2.4
            if (message.address == "/VMC/Ext/Light" &&
                (message.values[0] is string) && //name
                (message.values[1] is float) && //pos.x
                (message.values[2] is float) && //poy.y
                (message.values[3] is float) && //pos.z
                (message.values[4] is float) && //q.x
                (message.values[5] is float) && //q.y
                (message.values[6] is float) && //q.z
                (message.values[7] is float) && //q.w
                (message.values[8] is float) && //r
                (message.values[9] is float) && //g
                (message.values[10] is float) && //b
                (message.values[11] is float)    //a
                )
            {
                if (VMCControlledLight != null && VMCControlledLight.transform != null)
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];
                    col.r = (float)message.values[8];
                    col.g = (float)message.values[9];
                    col.b = (float)message.values[10];
                    col.a = (float)message.values[11];

                    VMCControlledLight.transform.localPosition = pos;
                    VMCControlledLight.transform.localRotation = rot;
                    VMCControlledLight.color = col;
                }
            }
        }
        //IExternalReceiverのリストを使って配信する
        public bool SendNextReceivers(uOSC.Message message, int callCount)
        {
            if (callCount > 100)
            {
                //無限ループ対策
                Debug.LogError("[ExternalReceiver] Too many call(maybe infinite loop).");
                return(false);
            }

            foreach (var r in receivers)
            {
                //インターフェースがあるか
                if (r != null)
                {
                    //Chain数を+1して次へ
                    r.MessageDaisyChain(ref message, callCount + 1);
                }
            }
            return(true);
        }
Exemplo n.º 7
0
        public void MessageDaisyChain(ref uOSC.Message message, int callCount)
        {
            //Startされていない場合無視
            if (externalReceiverManager == null || enabled == false || gameObject.activeInHierarchy == false)
            {
                return;
            }

            if (shutdown)
            {
                return;
            }

            StatusMessage = "OK";

            ProcessMessage(ref message);

            if (!externalReceiverManager.SendNextReceivers(message, callCount))
            {
                StatusMessage = "Infinite loop detected!";
                shutdown      = true;
            }
        }
Exemplo n.º 8
0
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //V2.4 背景色情報
            if (message.address == "/VMC/Ext/Setting/Color" &&
                (message.values[0] is float) &&
                (message.values[1] is float) &&
                (message.values[2] is float) &&
                (message.values[3] is float))
            {
                backgroundColor = new Color((float)message.values[0], (float)message.values[1], (float)message.values[2], (float)message.values[3]);
                BackgroundSphereRenderer.materials[0].SetColor(Shader.PropertyToID("_Color"), backgroundColor);
            }
            //V2.4 ウィンドウ情報
            else if (message.address == "/VMC/Ext/Setting/Win" &&
                     (message.values[0] is int) &&
                     (message.values[1] is int) &&
                     (message.values[2] is int) &&
                     (message.values[3] is int))
            {
                IsTopMost          = (int)message.values[0] != 0;
                IsTransparent      = (int)message.values[1] != 0;
                WindowClickThrough = (int)message.values[2] != 0;
                HideBorder         = (int)message.values[3] != 0;

                windowManager.SetWindowAlwaysTopMost(IsTopMost);
                windowManager.SetWindowBackgroundTransparent(IsTransparent, backgroundColor);
                windowManager.SetThroughMouseClick(WindowClickThrough);
                windowManager.SetWindowBorder(HideBorder);
            }
        }
Exemplo n.º 9
0
        //メッセージ処理本体
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //ルート位置がない場合
            if (RootPositionTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootPositionTransform = Model.transform;
            }

            //ルート回転がない場合
            if (RootRotationTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootRotationTransform = Model.transform;
            }

            //モーションデータ送信可否
            if (message.address == "/VMC/Ext/OK" &&
                (message.values[0] is int))
            {
                Available = (int)message.values[0];
                if (Available == 0)
                {
                    StatusMessage = "Waiting for [Load VRM]";
                }

                //V2.5 キャリブレーション状態(長さ3以上)
                if (message.values.Length >= 3)
                {
                    if ((message.values[1] is int) && (message.values[2] is int))
                    {
                        int calibrationState = (int)message.values[1];
                        int calibrationMode  = (int)message.values[2];

                        //キャリブレーション出来ていないときは隠す
                        if (HideInUncalibrated && Model != null)
                        {
                            Model.SetActive(calibrationState == 3);
                        }
                        //スケール同期をキャリブレーションと連動させる
                        if (SyncCalibrationModeWithScaleOffsetSynchronize)
                        {
                            RootScaleOffsetSynchronize = !(calibrationMode == 0); //通常モードならオフ、MR系ならオン
                        }
                    }
                }
                return;
            }
            //データ送信時刻
            else if (message.address == "/VMC/Ext/T" &&
                     (message.values[0] is float))
            {
                time = (float)message.values[0];
                PacketCounterInFrame++; //フレーム中のパケットフレーム数を測定
                return;
            }
            //VRM自動読み込み
            else if (message.address == "/VMC/Ext/VRM" &&
                     (message.values[0] is string) &&
                     (message.values[1] is string)
                     )
            {
                string path  = (string)message.values[0];
                string title = (string)message.values[1];

                //前回読み込んだパスと違う場合かつ、読み込みが許可されている場合
                if (path != loadedVRMPath && enableAutoLoadVRM == true)
                {
                    loadedVRMPath = path;
                    loadedVRMName = title;
                    LoadVRM(path);
                }
                return;
            }
            //オプション文字列
            else if (message.address == "/VMC/Ext/Opt" &&
                     (message.values[0] is string))
            {
                OptionString = (string)message.values[0];
                return;
            }


            //モデルがないか、モデル姿勢、ルート姿勢が取得できないなら以降何もしない
            if (Model == null || Model.transform == null || RootPositionTransform == null || RootRotationTransform == null)
            {
                return;
            }

            //Root姿勢
            if (message.address == "/VMC/Ext/Root/Pos" &&
                (message.values[0] is string) &&
                (message.values[1] is float) &&
                (message.values[2] is float) &&
                (message.values[3] is float) &&
                (message.values[4] is float) &&
                (message.values[5] is float) &&
                (message.values[6] is float) &&
                (message.values[7] is float)
                )
            {
                StatusMessage = "OK";

                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //位置同期
                if (RootPositionSynchronize)
                {
                    RootPositionTransform.localPosition = pos;
                }
                //回転同期
                if (RootRotationSynchronize)
                {
                    RootRotationTransform.localRotation = rot;
                }
                //スケール同期とオフセット補正(v2.1拡張プロトコルの場合のみ)
                if (RootScaleOffsetSynchronize && message.values.Length > RootPacketLengthOfScaleAndOffset &&
                    (message.values[8] is float) &&
                    (message.values[9] is float) &&
                    (message.values[10] is float) &&
                    (message.values[11] is float) &&
                    (message.values[12] is float) &&
                    (message.values[13] is float)
                    )
                {
                    scale.x  = 1.0f / (float)message.values[8];
                    scale.y  = 1.0f / (float)message.values[9];
                    scale.z  = 1.0f / (float)message.values[10];
                    offset.x = (float)message.values[11];
                    offset.y = (float)message.values[12];
                    offset.z = (float)message.values[13];

                    Model.transform.localScale          = scale;
                    RootPositionTransform.localPosition = Vector3.Scale(RootPositionTransform.localPosition, scale);

                    //位置同期が有効な場合のみオフセットを反映する
                    if (RootPositionSynchronize)
                    {
                        offset = Vector3.Scale(offset, scale);
                        RootPositionTransform.localPosition -= offset;
                    }
                }
                else
                {
                    Model.transform.localScale = Vector3.one;
                }
            }
            //ボーン姿勢
            else if (message.address == "/VMC/Ext/Bone/Pos" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float) &&
                     (message.values[2] is float) &&
                     (message.values[3] is float) &&
                     (message.values[4] is float) &&
                     (message.values[5] is float) &&
                     (message.values[6] is float) &&
                     (message.values[7] is float)
                     )
            {
                string boneName = (string)message.values[0];
                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //Humanoidボーンに該当するボーンがあるか調べる
                HumanBodyBones bone;
                if (HumanBodyBonesTryParse(ref boneName, out bone))
                {
                    //あれば位置と回転をキャッシュする
                    if (HumanBodyBonesPositionTable.ContainsKey(bone))
                    {
                        HumanBodyBonesPositionTable[bone] = pos;
                    }
                    else
                    {
                        HumanBodyBonesPositionTable.Add(bone, pos);
                    }

                    if (HumanBodyBonesRotationTable.ContainsKey(bone))
                    {
                        HumanBodyBonesRotationTable[bone] = rot;
                    }
                    else
                    {
                        HumanBodyBonesRotationTable.Add(bone, rot);
                    }
                }
                //受信と更新のタイミングは切り離した
            }
            //ブレンドシェープ同期
            else if (message.address == "/VMC/Ext/Blend/Val" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float)
                     )
            {
                //一旦変数に格納する
                string key   = (string)message.values[0];
                float  value = (float)message.values[1];

                //BlendShapeフィルタが有効なら
                if (BlendShapeFilterEnable)
                {
                    //フィルタテーブルに存在するか確認する
                    if (blendShapeFilterDictionaly.ContainsKey(key))
                    {
                        //存在する場合はフィルタ更新して値として反映する
                        blendShapeFilterDictionaly[key] = (blendShapeFilterDictionaly[key] * BlendShapeFilter) + value * (1.0f - BlendShapeFilter);
                        value = blendShapeFilterDictionaly[key];
                    }
                    else
                    {
                        //存在しない場合はフィルタに登録する。値はそのまま
                        blendShapeFilterDictionaly.Add(key, value);
                    }
                }

                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    //v0.56 BlendShape仕様変更対応
                    //辞書からKeyに変換し、Key値辞書に値を入れる

                    //通信で受信したキーを小文字に変換して非ケース化
                    string lowerKey = key.ToLower();

                    //キーに該当するBSKeyが存在するかチェックする
                    BlendShapeKey bskey;
                    if (StringToBlendShapeKeyDictionary.TryGetValue(lowerKey, out bskey))
                    {
                        //キーに対して値を登録する
                        BlendShapeToValueDictionary[bskey] = value;

                        //Debug.Log("[lowerKey]->"+ lowerKey+" [bskey]->"+bskey.ToString()+" [value]->"+value);
                    }
                    else
                    {
                        //そんなキーは無い
                        //Debug.LogError("[lowerKey]->" + lowerKey + " is not found");
                    }
                }
            }
            //ブレンドシェープ適用
            else if (message.address == "/VMC/Ext/Blend/Apply")
            {
                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    blendShapeProxy.SetValues(BlendShapeToValueDictionary);
                }
            }
        }
Exemplo n.º 10
0
 //データ受信イベント
 private void OnDataReceived(uOSC.Message message)
 {
     //チェーン数0としてデイジーチェーンを発生させる
     MessageDaisyChain(ref message, 0);
 }
Exemplo n.º 11
0
        //メッセージ処理本体
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //ルート位置がない場合
            if (RootPositionTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootPositionTransform = Model.transform;
            }

            //ルート回転がない場合
            if (RootRotationTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootRotationTransform = Model.transform;
            }

            //モーションデータ送信可否
            if (message.address == "/VMC/Ext/OK" &&
                (message.values[0] is int))
            {
                Available = (int)message.values[0];
                if (Available == 0)
                {
                    StatusMessage = "Waiting for [Load VRM]";
                }

                //V2.5 キャリブレーション状態(長さ3以上)
                if (message.values.Length >= 3)
                {
                    if ((message.values[1] is int) && (message.values[2] is int))
                    {
                        int calibrationState = (int)message.values[1];
                        int calibrationMode  = (int)message.values[2];

                        //キャリブレーション出来ていないときは隠す
                        if (HideInUncalibrated && Model != null)
                        {
                            Model.SetActive(calibrationState == 3);
                        }
                        //スケール同期をキャリブレーションと連動させる
                        if (SyncCalibrationModeWithScaleOffsetSynchronize)
                        {
                            RootScaleOffsetSynchronize = !(calibrationMode == 0); //通常モードならオフ、MR系ならオン
                        }
                    }
                }
                return;
            }
            //データ送信時刻
            else if (message.address == "/VMC/Ext/T" &&
                     (message.values[0] is float))
            {
                time = (float)message.values[0];
                PacketCounterInFrame++; //フレーム中のパケットフレーム数を測定
                return;
            }
            //VRM自動読み込み
            else if (message.address == "/VMC/Ext/VRM" &&
                     (message.values[0] is string) &&
                     (message.values[1] is string)
                     )
            {
                string path  = (string)message.values[0];
                string title = (string)message.values[1];

                //前回読み込んだパスと違う場合かつ、読み込みが許可されている場合
                if (path != loadedVRMPath && enableAutoLoadVRM == true)
                {
                    loadedVRMPath = path;
                    loadedVRMName = title;
                    LoadVRM(path);
                }
                return;
            }
            //オプション文字列
            else if (message.address == "/VMC/Ext/Opt" &&
                     (message.values[0] is string))
            {
                OptionString = (string)message.values[0];
                return;
            }


            //モデルがないか、モデル姿勢、ルート姿勢が取得できないなら以降何もしない
            if (Model == null || Model.transform == null || RootPositionTransform == null || RootRotationTransform == null)
            {
                return;
            }

            //Root姿勢
            if (message.address == "/VMC/Ext/Root/Pos" &&
                (message.values[0] is string) &&
                (message.values[1] is float) &&
                (message.values[2] is float) &&
                (message.values[3] is float) &&
                (message.values[4] is float) &&
                (message.values[5] is float) &&
                (message.values[6] is float) &&
                (message.values[7] is float)
                )
            {
                StatusMessage = "OK";

                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //位置同期
                if (RootPositionSynchronize)
                {
                    RootPositionTransform.localPosition = pos;
                }
                //回転同期
                if (RootRotationSynchronize)
                {
                    RootRotationTransform.localRotation = rot;
                }
                //スケール同期とオフセット補正(v2.1拡張プロトコルの場合のみ)
                if (RootScaleOffsetSynchronize && message.values.Length > RootPacketLengthOfScaleAndOffset &&
                    (message.values[8] is float) &&
                    (message.values[9] is float) &&
                    (message.values[10] is float) &&
                    (message.values[11] is float) &&
                    (message.values[12] is float) &&
                    (message.values[13] is float)
                    )
                {
                    scale.x  = 1.0f / (float)message.values[8];
                    scale.y  = 1.0f / (float)message.values[9];
                    scale.z  = 1.0f / (float)message.values[10];
                    offset.x = (float)message.values[11];
                    offset.y = (float)message.values[12];
                    offset.z = (float)message.values[13];

                    Model.transform.localScale          = scale;
                    RootPositionTransform.localPosition = Vector3.Scale(RootPositionTransform.localPosition, scale);

                    //位置同期が有効な場合のみオフセットを反映する
                    if (RootPositionSynchronize)
                    {
                        offset = Vector3.Scale(offset, scale);
                        RootPositionTransform.localPosition -= offset;
                    }
                }
                else
                {
                    Model.transform.localScale = Vector3.one;
                }
            }
            //ボーン姿勢
            else if (message.address == "/VMC/Ext/Bone/Pos" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float) &&
                     (message.values[2] is float) &&
                     (message.values[3] is float) &&
                     (message.values[4] is float) &&
                     (message.values[5] is float) &&
                     (message.values[6] is float) &&
                     (message.values[7] is float)
                     )
            {
                string boneName = (string)message.values[0];
                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //Humanoidボーンに該当するボーンがあるか調べる
                HumanBodyBones bone;
                if (HumanBodyBonesTryParse(ref boneName, out bone))
                {
                    //あれば位置と回転をキャッシュする
                    if (HumanBodyBonesPositionTable.ContainsKey(bone))
                    {
                        HumanBodyBonesPositionTable[bone] = pos;
                    }
                    else
                    {
                        HumanBodyBonesPositionTable.Add(bone, pos);
                    }

                    if (HumanBodyBonesRotationTable.ContainsKey(bone))
                    {
                        HumanBodyBonesRotationTable[bone] = rot;
                    }
                    else
                    {
                        HumanBodyBonesRotationTable.Add(bone, rot);
                    }
                }
                //受信と更新のタイミングは切り離した
            }
            //ブレンドシェープ同期
            else if (message.address == "/VMC/Ext/Blend/Val" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float)
                     )
            {
                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    //v0.55ブレンドシェープ仕様変更対応
                    //ワークアラウンドが有効か
                    if (VRMVersion.MAJOR >= 0 && VRMVersion.MINOR > 53 && BlendShapeCaseWorkAround)
                    {
                        //まず、小文字変換テーブルを作成する
                        string RawKey             = (string)message.values[0];
                        string CaseSensitiveKey   = "";
                        string NoCaseSensitiveKey = "";

                        //小文字変換テーブルに存在しなければ
                        if (!blendShapeProxyCaseBuffer.TryGetValue(RawKey, out NoCaseSensitiveKey))
                        {
                            //小文字変換テーブルに登録する
                            blendShapeProxyCaseBuffer[RawKey] = RawKey.ToLower();
                            NoCaseSensitiveKey = RawKey.ToLower();

                            //Debug.Log("Register to CaseBuffer:" + RawKey + " -> " + NoCaseSensitiveKey);
                        }

                        //小文字変換された結果で、まずプリセットに存在するか確認する
                        string           presetName = "";
                        BlendShapePreset preset     = BlendShapePreset.Unknown;
                        //プリセット変換テーブルで見つかるか
                        if (BlendShapePresetCaseConverter.TryGetValue(NoCaseSensitiveKey, out presetName))
                        {
                            //ENUMテーブルで見つかるか
                            if (BlendShapePresetTryParse(ref presetName, out preset))
                            {
                                //見つかった
                                blendShapeProxy.AccumulateValue(preset, (float)message.values[1]);
                                //Debug.Log("Key Found: " + NoCaseSensitiveKey + "->" + preset.ToString());
                            }
                            else
                            {
                                //見つからない
                                preset = BlendShapePreset.Unknown;
                            }
                        }
                        else
                        {
                            //見つからない
                            preset = BlendShapePreset.Unknown;
                        }

                        //プリセットに該当するものがなかった場合
                        if (preset == BlendShapePreset.Unknown)
                        {
                            //小文字変換された結果を使って、ケースセンシティブな文字列に変換する
                            if (blendShapeProxyCaseConverter.TryGetValue(NoCaseSensitiveKey, out CaseSensitiveKey))
                            {
                                //独自キーとしてUniVRMにわたす
                                blendShapeProxy.AccumulateValue(CaseSensitiveKey, (float)message.values[1]);
                                //Debug.Log("Key Convert: " + NoCaseSensitiveKey + "->" + CaseSensitiveKey);
                            }
                            else
                            {
                                //Debug.Log("Key not found");
                            }
                        }
                    }
                    else
                    {
                        //通常通り適用する
                        blendShapeProxy.AccumulateValue((string)message.values[0], (float)message.values[1]);
                    }
                }
            }
            //ブレンドシェープ適用
            else if (message.address == "/VMC/Ext/Blend/Apply")
            {
                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    blendShapeProxy.Apply();
                }
            }
        }
 SteamVR_Utils.RigidTransform SetTransform(ref Vector3 pos, ref Quaternion rot, ref uOSC.Message message)
 {
     pos.x = (float)message.values[1];
     pos.y = (float)message.values[2];
     pos.z = (float)message.values[3];
     rot.x = (float)message.values[4];
     rot.y = (float)message.values[5];
     rot.z = (float)message.values[6];
     rot.w = (float)message.values[7];
     return(new SteamVR_Utils.RigidTransform(pos, rot));
 }
        void OnDataReceived(uOSC.Message message)
        {
            //有効なとき以外処理しない
            if (this.isActiveAndEnabled)
            {
                //生存チェックのためのパケットカウンタ
                packets++;
                if (packets > int.MaxValue / 2)
                {
                    packets = 0;
                }

                //仮想コントローラー V2.3
                if (message.address == "/VMC/Ext/Con/Pos" &&
                    (message.values[0] is string) &&
                    (message.values[1] is float) &&
                    (message.values[2] is float) &&
                    (message.values[3] is float) &&
                    (message.values[4] is float) &&
                    (message.values[5] is float) &&
                    (message.values[6] is float) &&
                    (message.values[7] is float)
                    )
                {
                    string serial         = (string)message.values[0];
                    var    rigidTransform = SetTransform(ref pos, ref rot, ref message);

                    lock (LockObject)
                    {
                        if (virtualController.ContainsKey(serial))
                        {
                            virtualController[serial] = rigidTransform;
                        }
                        else
                        {
                            virtualController.Add(serial, rigidTransform);
                            virtualControllerFiltered.Add(serial, rigidTransform);
                        }
                    }
                }
                //仮想トラッカー V2.3
                else if ((message.address == "/VMC/Ext/Hmd/Pos" ||
                          message.address == "/VMC/Ext/Tra/Pos") &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    string serial         = (string)message.values[0];
                    var    rigidTransform = SetTransform(ref pos, ref rot, ref message);

                    lock (LockObject)
                    {
                        if (virtualTracker.ContainsKey(serial))
                        {
                            virtualTracker[serial] = rigidTransform;
                        }
                        else
                        {
                            virtualTracker.Add(serial, rigidTransform);
                            virtualTrackerFiltered.Add(serial, rigidTransform);
                        }
                    }
                }
                //フレーム設定 V2.3
                else if (message.address == "/VMC/Ext/Set/Period" &&
                         (message.values[0] is int) &&
                         (message.values[1] is int) &&
                         (message.values[2] is int) &&
                         (message.values[3] is int) &&
                         (message.values[4] is int) &&
                         (message.values[5] is int)
                         )
                {
                    externalSender.periodStatus     = (int)message.values[0];
                    externalSender.periodRoot       = (int)message.values[1];
                    externalSender.periodBone       = (int)message.values[2];
                    externalSender.periodBlendShape = (int)message.values[3];
                    externalSender.periodCamera     = (int)message.values[4];
                    externalSender.periodDevices    = (int)message.values[5];
                }
                //Virtual MIDI CC V2.3
                else if (message.address == "/VMC/Ext/Midi/CC/Val" &&
                         (message.values[0] is int) &&
                         (message.values[1] is float)
                         )
                {
                    MIDICCWrapper.KnobUpdated(0, (int)message.values[0], (float)message.values[1]);
                }
                //Camera Control V2.3
                else if (message.address == "/VMC/Ext/Cam" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float) &&
                         (message.values[8] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];
                    float fov = (float)message.values[8];

                    //FreeCameraじゃなかったらFreeCameraにする
                    if (Settings.Current.CameraType != UnityMemoryMappedFile.CameraTypes.Free)
                    {
                        CameraManager.Current.ChangeCamera(UnityMemoryMappedFile.CameraTypes.Free);
                    }

                    //カメラ制御を切る
                    CameraManager.Current.FreeCamera.GetComponent <CameraMouseControl>().enabled = false;

                    //座標とFOVを適用
                    CameraManager.Current.FreeCamera.transform.localPosition = pos;
                    CameraManager.Current.FreeCamera.transform.localRotation = rot;
                    CameraManager.Current.ControlCamera.fieldOfView          = fov;
                } //ブレンドシェープ同期
                else if (message.address == "/VMC/Ext/Blend/Val" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float)
                         )
                {
                    blendShapeBuffer[(string)message.values[0]] = (float)message.values[1];
                }
                //ブレンドシェープ適用
                else if (message.address == "/VMC/Ext/Blend/Apply")
                {
                    if (DisableBlendShapeReception == true)
                    {
                        blendShapeBuffer.Clear();
                    }

                    faceController.MixPresets(nameof(ExternalReceiverForVMC), blendShapeBuffer.Keys.ToArray(), blendShapeBuffer.Values.ToArray());
                    blendShapeBuffer.Clear();
                }//外部アイトラ V2.3
                else if (message.address == "/VMC/Ext/Set/Eye" &&
                         (message.values[0] is int) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float)
                         )
                {
                    bool enable = ((int)message.values[0]) != 0;
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];

                    if (enable)
                    {
                        //ターゲットが存在しなければ作る
                        if (lookTargetOSC == null)
                        {
                            lookTargetOSC      = new GameObject();
                            lookTargetOSC.name = "lookTargetOSC";
                        }
                        //位置を書き込む
                        if (lookTargetOSC.transform != null)
                        {
                            lookTargetOSC.transform.parent        = headTransform;
                            lookTargetOSC.transform.localPosition = pos;
                        }

                        //視線に書き込む
                        if (vrmLookAtHead != null && setFaceApplyAction == false)
                        {
                            faceController.BeforeApply += beforeFaceApply;
                            setFaceApplyAction          = true;
                        }
                    }
                    else
                    {
                        //視線を止める
                        if (vrmLookAtHead != null && setFaceApplyAction == true)
                        {
                            faceController.BeforeApply -= beforeFaceApply;
                            setFaceApplyAction          = false;
                        }
                    }
                }
                //情報要求 V2.4
                else if (message.address == "/VMC/Ext/Set/Req")
                {
                    if (externalSender.isActiveAndEnabled && externalSender.uClient != null)
                    {
                        externalSender.SendPerLowRate(); //即時送信
                    }
                }
                //情報表示 V2.4
                else if (message.address == "/VMC/Ext/Set/Res" && (message.values[0] is string))
                {
                    statusString = (string)message.values[0];
                }
                //キャリブレーション準備 V2.5
                else if (message.address == "/VMC/Ext/Set/Calib/Ready")
                {
                    if (File.Exists(Settings.Current.VRMPath))
                    {
                        window.ImportVRM(Settings.Current.VRMPath, true, true, true);
                    }
                }
                //キャリブレーション実行 V2.5
                else if (message.address == "/VMC/Ext/Set/Calib/Exec" && (message.values[0] is int))
                {
                    PipeCommands.CalibrateType calibrateType = PipeCommands.CalibrateType.Default;

                    switch ((int)message.values[0])
                    {
                    case 0:
                        calibrateType = PipeCommands.CalibrateType.Default;
                        break;

                    case 1:
                        calibrateType = PipeCommands.CalibrateType.FixedHand;
                        break;

                    case 2:
                        calibrateType = PipeCommands.CalibrateType.FixedHandWithGround;
                        break;

                    default: return;     //無視
                    }
                    StartCoroutine(window.Calibrate(calibrateType));
                    Invoke("EndCalibrate", 2f);
                }
                //設定読み込み V2.5
                else if (message.address == "/VMC/Ext/Set/Config" && (message.values[0] is string))
                {
                    string path = (string)message.values[0];
                    if (File.Exists(path))
                    {
                        //なぜか時間がかかる
                        window.LoadSettings(path);
                    }
                }
                //スルー情報 V2.6
                else if (message.address != null && message.address.StartsWith("/VMC/Thru/"))
                {
                    //転送する
                    if (externalSender.isActiveAndEnabled && externalSender.uClient != null)
                    {
                        externalSender.uClient.Send(message.address, message.values);
                    }
                }
                //Directional Light V2.9
                else if (message.address == "/VMC/Ext/Light" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float) &&
                         (message.values[8] is float) &&
                         (message.values[9] is float) &&
                         (message.values[10] is float) &&
                         (message.values[11] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];
                    float r = (float)message.values[8];
                    float g = (float)message.values[9];
                    float b = (float)message.values[10];
                    float a = (float)message.values[11];

                    window.MainDirectionalLight.color             = new Color(r, g, b, a);
                    window.MainDirectionalLightTransform.position = pos;
                    window.MainDirectionalLightTransform.rotation = rot;
                }

                //ボーン姿勢
                else if (message.address == "/VMC/Ext/Bone/Pos" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    string boneName = (string)message.values[0];
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    //Humanoidボーンに該当するボーンがあるか調べる
                    HumanBodyBones bone;
                    if (HumanBodyBonesTryParse(ref boneName, out bone))
                    {
                        //あれば位置と回転をキャッシュする
                        if (HumanBodyBonesPositionTable.ContainsKey(bone))
                        {
                            HumanBodyBonesPositionTable[bone] = pos;
                        }
                        else
                        {
                            HumanBodyBonesPositionTable.Add(bone, pos);
                        }

                        if (HumanBodyBonesRotationTable.ContainsKey(bone))
                        {
                            HumanBodyBonesRotationTable[bone] = rot;
                        }
                        else
                        {
                            HumanBodyBonesRotationTable.Add(bone, rot);
                        }
                    }
                    //受信と更新のタイミングは切り離した
                }
            }
        }
Exemplo n.º 14
0
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //コントローラ操作情報 v2.1
            if (message.address == "/VMC/Ext/Con" &&
                (message.values[0] is int) &&
                (message.values[1] is string) &&
                (message.values[2] is int) &&
                (message.values[3] is int) &&
                (message.values[4] is int) &&
                (message.values[5] is float) &&
                (message.values[6] is float) &&
                (message.values[7] is float)
                )
            {
                con.active  = (int)message.values[0];
                con.name    = (string)message.values[1];
                con.IsLeft  = (int)message.values[2];
                con.IsTouch = (int)message.values[3];
                con.IsAxis  = (int)message.values[4];
                con.Axis.x  = (float)message.values[5];
                con.Axis.y  = (float)message.values[6];
                con.Axis.z  = (float)message.values[7];

                //イベントを呼び出す
                if (ControllerInputAction != null)
                {
                    ControllerInputAction.Invoke(con);
                }
                if (con.IsAxis == 0)
                {
                    if (con.IsLeft == 1)
                    {
                        LastInput = "Left-" + con.name + " = " + con.active;
                        InputDictionary["Left-" + con.name] = (con.active != 0);
                    }
                    else
                    {
                        LastInput = "Right-" + con.name + " = " + con.active;
                        InputDictionary["Right-" + con.name] = (con.active != 0);
                    }
                }
            }
            //キーボード操作情報 v2.1
            else if (message.address == "/VMC/Ext/Key" &&
                     (message.values[0] is int) &&
                     (message.values[1] is string) &&
                     (message.values[2] is int)
                     )
            {
                key.active  = (int)message.values[0];
                key.name    = (string)message.values[1];
                key.keycode = (int)message.values[2];

                //イベントを呼び出す
                if (KeyInputAction != null)
                {
                    KeyInputAction.Invoke(key);
                }

                LastInput = "Key-" + key.name + " = " + key.active + " (" + key.keycode + ")";
            }
            // v2.2
            else if (message.address == "/VMC/Ext/Midi/Note" &&
                     (message.values[0] is int) &&
                     (message.values[1] is int) &&
                     (message.values[2] is int) &&
                     (message.values[3] is float)
                     )
            {
                note.active   = (int)message.values[0];
                note.channel  = (int)message.values[1];
                note.note     = (int)message.values[2];
                note.velocity = (float)message.values[3];

                //イベントを呼び出す
                if (MidiNoteInputAction != null)
                {
                    MidiNoteInputAction.Invoke(note);
                }

                LastInput = "Note-" + note.note + " = " + note.active + "/" + note.channel + "/" + note.velocity;
                InputDictionary["Note-" + note.note] = (note.active != 0);
            }
            // v2.2
            else if (message.address == "/VMC/Ext/Midi/CC/Val" &&
                     (message.values[0] is int) &&
                     (message.values[1] is float)
                     )
            {
                ccvalue.knob  = (int)message.values[0];
                ccvalue.value = (float)message.values[1];

                //イベントを呼び出す
                if (MidiCCValueInputAction != null)
                {
                    MidiCCValueInputAction.Invoke(ccvalue);
                }

                LastInput = "CC Val " + ccvalue.knob + " = " + ccvalue.value;

                if (ccvalue.knob >= 0 && ccvalue.knob < 128)
                {
                    CCValuesMonitor[ccvalue.knob] = ccvalue.value;
                }
            }
            // v2.2
            else if (message.address == "/VMC/Ext/Midi/CC/Bit" &&
                     (message.values[0] is int) &&
                     (message.values[1] is int)
                     )
            {
                ccbutton.knob   = (int)message.values[0];
                ccbutton.active = (int)message.values[1];

                //イベントを呼び出す
                if (MidiCCButtonInputAction != null)
                {
                    MidiCCButtonInputAction.Invoke(ccbutton);
                }
                LastInput = "CC-" + ccbutton.knob + " = " + ccbutton.active;
                InputDictionary["CC-" + ccbutton.knob] = (ccbutton.active != 0);
            }
        }
Exemplo n.º 15
0
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            if (manager.receiver.isLoading)
            {
                //ローカル読込中は処理しない
                return;
            }

            if (manager.status.DVRC_AuthState != "AUTHENTICATION_OK")
            {
                //ログインしていない場合は受け付けない
                return;
            }

            if (message.address == "/VMC/Ext/Remote" &&
                (message.values[0] is string) && //service
                (message.values[1] is string)    //json
                )
            {
                string service = message.values[0] as string;
                string json    = message.values[1] as string;

                if (service == "dmmvrconnect")
                {
                    var connect = JsonUtility.FromJson <dmmvrconnect>(json);
                    if (user_id != connect.user_id || avatar_id != connect.avatar_id)
                    {
                        user_id   = connect.user_id;
                        avatar_id = connect.avatar_id;

                        //メインスレッドに渡す
                        synchronizationContext.Post(async _ => {
                            Debug.Log("Avatar loading from Connect...");
                            var current_user = await Authentication.Instance.Okami.GetCurrentUserAsync();
                            if (user_id == current_user.id)
                            {
                                var avatar = await Authentication.Instance.Okami.GetAvatarAsync(current_user.id, avatar_id);
                                Debug.Log(avatar);
                                if (avatar != null)
                                {
                                    await manager.LoadAvatarFromDVRSDK(avatar);
                                }
                                else
                                {
                                    Debug.LogError("Avatar loading from Connect... Failed!");
                                }
                                Debug.Log("Load from connect OK");
                            }
                            else
                            {
                                Debug.Log("User id unmatch");
                            }
                        }, null);
                    }
                }
                else
                {
                    StatusMessage = "Unknown service: " + service;
                }
            }
        }
Exemplo n.º 16
0
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            if (!RealPosition)
            {
                if (message.address == "/VMC/Ext/Hmd/Pos" &&
                    (message.values[0] is string) &&
                    (message.values[1] is float) &&
                    (message.values[2] is float) &&
                    (message.values[3] is float) &&
                    (message.values[4] is float) &&
                    (message.values[5] is float) &&
                    (message.values[6] is float) &&
                    (message.values[7] is float)
                    )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("HMD", (string)message.values[0], pos, rot);
                    //Debug.Log("HMD pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
                // v2.2
                else if (message.address == "/VMC/Ext/Con/Pos" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("Controller", (string)message.values[0], pos, rot);
                    //Debug.Log("Con pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
                // v2.2
                else if (message.address == "/VMC/Ext/Tra/Pos" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("Tracker", (string)message.values[0], pos, rot);
                    //Debug.Log("Tra pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
            }
            else
            {
                if (message.address == "/VMC/Ext/Hmd/Pos/Local" &&
                    (message.values[0] is string) &&
                    (message.values[1] is float) &&
                    (message.values[2] is float) &&
                    (message.values[3] is float) &&
                    (message.values[4] is float) &&
                    (message.values[5] is float) &&
                    (message.values[6] is float) &&
                    (message.values[7] is float)
                    )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("HMD", (string)message.values[0], pos, rot);
                    //Debug.Log("HMD pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
                // v2.2
                else if (message.address == "/VMC/Ext/Con/Pos/Local" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("Controller", (string)message.values[0], pos, rot);
                    //Debug.Log("Con pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
                // v2.2
                else if (message.address == "/VMC/Ext/Tra/Pos/Local" &&
                         (message.values[0] is string) &&
                         (message.values[1] is float) &&
                         (message.values[2] is float) &&
                         (message.values[3] is float) &&
                         (message.values[4] is float) &&
                         (message.values[5] is float) &&
                         (message.values[6] is float) &&
                         (message.values[7] is float)
                         )
                {
                    pos.x = (float)message.values[1];
                    pos.y = (float)message.values[2];
                    pos.z = (float)message.values[3];
                    rot.x = (float)message.values[4];
                    rot.y = (float)message.values[5];
                    rot.z = (float)message.values[6];
                    rot.w = (float)message.values[7];

                    devideUpdate("Tracker", (string)message.values[0], pos, rot);
                    //Debug.Log("Tra pos " + (string)message.values[0] + " : " + pos + "/" + rot);
                }
            }
        }
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            if (message.address == "/VMC/Ext/OK" &&
                (message.values[0] is int))
            {
                Available = (int)message.values[0];
                if (Available == 0)
                {
                    StatusMessage = "Waiting for [Load VRM]";
                }
                else
                {
                    StatusMessage = "OK";
                }

                //V2.5 キャリブレーション状態
                if ((message.values[1] is int) && (message.values[2] is int))
                {
                    calibrationState = (CalibrationState)message.values[1];
                    calibrationMode  = (CalibrationMode)message.values[2];
                }
            }
            //データ送信時刻
            else if (message.address == "/VMC/Ext/T" &&
                     (message.values[0] is float))
            {
                time = (float)message.values[0];
            }
            //V2.4 受信情報
            else if (message.address == "/VMC/Ext/Rcv" &&
                     (message.values[0] is int) &&
                     (message.values[1] is int))
            {
                ReceiveEnable = (int)message.values[0] != 0;
                ReceivePort   = (int)message.values[1];
            }
            //V2.4 背景色情報
            else if (message.address == "/VMC/Ext/Setting/Color" &&
                     (message.values[0] is float) &&
                     (message.values[1] is float) &&
                     (message.values[2] is float) &&
                     (message.values[3] is float))
            {
                backgroundColor = new Color((float)message.values[0], (float)message.values[1], (float)message.values[2], (float)message.values[3]);
            }
            //V2.4 ウィンドウ情報
            else if (message.address == "/VMC/Ext/Setting/Win" &&
                     (message.values[0] is int) &&
                     (message.values[1] is int) &&
                     (message.values[2] is int) &&
                     (message.values[3] is int))
            {
                IsTopMost          = (int)message.values[0] != 0;
                IsTransparent      = (int)message.values[1] != 0;
                WindowClickThrough = (int)message.values[2] != 0;
                HideBorder         = (int)message.values[3] != 0;
            }
            //V2.5 読み込み済み設定ファイルパス情報
            else if (message.address == "/VMC/Ext/Config" &&
                     (message.values[0] is string))
            {
                LoadedConfigPath = (string)message.values[0];
            }
        }
Exemplo n.º 18
0
        //メッセージ処理本体
        private void ProcessMessage(ref uOSC.Message message)
        {
            //メッセージアドレスがない、あるいはメッセージがない不正な形式の場合は処理しない
            if (message.address == null || message.values == null)
            {
                StatusMessage = "Bad message.";
                return;
            }

            //ルート位置がない場合
            if (RootPositionTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootPositionTransform = Model.transform;
            }

            //ルート回転がない場合
            if (RootRotationTransform == null && Model != null)
            {
                //モデル姿勢をルート姿勢にする
                RootRotationTransform = Model.transform;
            }

            //モーションデータ送信可否
            if (message.address == "/VMC/Ext/OK" &&
                (message.values[0] is int))
            {
                Available = (int)message.values[0];
                if (Available == 0)
                {
                    StatusMessage = "Waiting for [Load VRM]";
                }

                //V2.5 キャリブレーション状態(長さ3以上)
                if (message.values.Length >= 3)
                {
                    if ((message.values[1] is int) && (message.values[2] is int))
                    {
                        int calibrationState = (int)message.values[1];
                        int calibrationMode  = (int)message.values[2];

                        //キャリブレーション出来ていないときは隠す
                        if (HideInUncalibrated && Model != null)
                        {
                            Model.SetActive(calibrationState == 3);
                        }
                        //スケール同期をキャリブレーションと連動させる
                        if (SyncCalibrationModeWithScaleOffsetSynchronize)
                        {
                            RootScaleOffsetSynchronize = !(calibrationMode == 0); //通常モードならオフ、MR系ならオン
                        }
                    }
                }
                return;
            }
            //データ送信時刻
            else if (message.address == "/VMC/Ext/T" &&
                     (message.values[0] is float))
            {
                time = (float)message.values[0];
                PacketCounterInFrame++; //フレーム中のパケットフレーム数を測定
                return;
            }
            //VRM自動読み込み
            else if (message.address == "/VMC/Ext/VRM" &&
                     (message.values[0] is string) &&
                     (message.values[1] is string)
                     )
            {
                string path  = (string)message.values[0];
                string title = (string)message.values[1];

                //前回読み込んだパスと違う場合かつ、読み込みが許可されている場合
                if (path != loadedVRMPath && enableAutoLoadVRM == true)
                {
                    loadedVRMPath = path;
                    loadedVRMName = title;
                    LoadVRM(path);
                }
                return;
            }
            //オプション文字列
            else if (message.address == "/VMC/Ext/Opt" &&
                     (message.values[0] is string))
            {
                OptionString = (string)message.values[0];
                return;
            }


            //モデルがないか、モデル姿勢、ルート姿勢が取得できないなら以降何もしない
            if (Model == null || Model.transform == null || RootPositionTransform == null || RootRotationTransform == null)
            {
                return;
            }

            //Root姿勢
            if (message.address == "/VMC/Ext/Root/Pos" &&
                (message.values[0] is string) &&
                (message.values[1] is float) &&
                (message.values[2] is float) &&
                (message.values[3] is float) &&
                (message.values[4] is float) &&
                (message.values[5] is float) &&
                (message.values[6] is float) &&
                (message.values[7] is float)
                )
            {
                StatusMessage = "OK";

                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //位置同期
                if (RootPositionSynchronize)
                {
                    RootPositionTransform.localPosition = pos;
                }
                //回転同期
                if (RootRotationSynchronize)
                {
                    RootRotationTransform.localRotation = rot;
                }
                //スケール同期とオフセット補正(v2.1拡張プロトコルの場合のみ)
                if (RootScaleOffsetSynchronize && message.values.Length > RootPacketLengthOfScaleAndOffset &&
                    (message.values[8] is float) &&
                    (message.values[9] is float) &&
                    (message.values[10] is float) &&
                    (message.values[11] is float) &&
                    (message.values[12] is float) &&
                    (message.values[13] is float)
                    )
                {
                    scale.x  = 1.0f / (float)message.values[8];
                    scale.y  = 1.0f / (float)message.values[9];
                    scale.z  = 1.0f / (float)message.values[10];
                    offset.x = (float)message.values[11];
                    offset.y = (float)message.values[12];
                    offset.z = (float)message.values[13];

                    Model.transform.localScale          = scale;
                    RootPositionTransform.localPosition = Vector3.Scale(RootPositionTransform.localPosition, scale);

                    //位置同期が有効な場合のみオフセットを反映する
                    if (RootPositionSynchronize)
                    {
                        offset = Vector3.Scale(offset, scale);
                        RootPositionTransform.localPosition -= offset;
                    }
                }
                else
                {
                    Model.transform.localScale = Vector3.one;
                    scale  = Vector3.one;
                    offset = Vector3.zero;
                }
            }
            //ボーン姿勢
            else if (message.address == "/VMC/Ext/Bone/Pos" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float) &&
                     (message.values[2] is float) &&
                     (message.values[3] is float) &&
                     (message.values[4] is float) &&
                     (message.values[5] is float) &&
                     (message.values[6] is float) &&
                     (message.values[7] is float)
                     )
            {
                string boneName = (string)message.values[0];
                pos.x = (float)message.values[1];
                pos.y = (float)message.values[2];
                pos.z = (float)message.values[3];
                rot.x = (float)message.values[4];
                rot.y = (float)message.values[5];
                rot.z = (float)message.values[6];
                rot.w = (float)message.values[7];

                //Humanoidボーンに該当するボーンがあるか調べる
                HumanBodyBones bone;
                if (HumanBodyBonesTryParse(ref boneName, out bone))
                {
                    //あれば位置と回転をキャッシュする
                    if (HumanBodyBonesPositionTable.ContainsKey(bone))
                    {
                        HumanBodyBonesPositionTable[bone] = pos;
                    }
                    else
                    {
                        HumanBodyBonesPositionTable.Add(bone, pos);
                    }

                    if (HumanBodyBonesRotationTable.ContainsKey(bone))
                    {
                        HumanBodyBonesRotationTable[bone] = rot;
                    }
                    else
                    {
                        HumanBodyBonesRotationTable.Add(bone, rot);
                    }
                }
                //受信と更新のタイミングは切り離した
            }
            //ブレンドシェープ同期
            else if (message.address == "/VMC/Ext/Blend/Val" &&
                     (message.values[0] is string) &&
                     (message.values[1] is float)
                     )
            {
                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    blendShapeProxy.AccumulateValue((string)message.values[0], (float)message.values[1]);
                }
            }
            //ブレンドシェープ適用
            else if (message.address == "/VMC/Ext/Blend/Apply")
            {
                if (BlendShapeSynchronize && blendShapeProxy != null)
                {
                    blendShapeProxy.Apply();
                }
            }
        }