Exemple #1
0
    //低頻度(1秒以上)で送信する情報もの。ただし送信要求が来たら即時発信する
    public void SendPerLowRate()
    {
        //status送信が無効な場合はこれらも送信しない
        if (periodStatus != 0)
        {
            uOSC.Bundle infoBundle = new uOSC.Bundle(uOSC.Timestamp.Immediate);
            //受信有効情報(Receive enable)
            //有効可否と、ポート番号の送信
            infoBundle.Add(new uOSC.Message("/VMC/Ext/Rcv", (int)(externalReceiver.isActiveAndEnabled ? 1 : 0), externalReceiver.receivePort));


            //【イベント送信】DirectionalLight位置・色(DirectionalLight transform & color)
            if ((window.MainDirectionalLightTransform != null) && (window.MainDirectionalLight.color != null))
            {
                infoBundle.Add(new uOSC.Message("/VMC/Ext/Light",
                                                "Light",
                                                window.MainDirectionalLightTransform.position.x, window.MainDirectionalLightTransform.position.y, window.MainDirectionalLightTransform.position.z,
                                                window.MainDirectionalLightTransform.rotation.x, window.MainDirectionalLightTransform.rotation.y, window.MainDirectionalLightTransform.rotation.z, window.MainDirectionalLightTransform.rotation.w,
                                                window.MainDirectionalLight.color.r, window.MainDirectionalLight.color.g, window.MainDirectionalLight.color.b, window.MainDirectionalLight.color.a));
            }

            //【イベント送信】現在の設定
            infoBundle.Add(new uOSC.Message("/VMC/Ext/Setting/Color",
                                            ControlWPFWindow.CurrentSettings.BackgroundColor.r,
                                            ControlWPFWindow.CurrentSettings.BackgroundColor.g,
                                            ControlWPFWindow.CurrentSettings.BackgroundColor.b,
                                            ControlWPFWindow.CurrentSettings.BackgroundColor.a
                                            ));
            infoBundle.Add(new uOSC.Message("/VMC/Ext/Setting/Win",
                                            ControlWPFWindow.CurrentSettings.IsTopMost ? 1 : 0,
                                            ControlWPFWindow.CurrentSettings.IsTransparent ? 1 : 0,
                                            ControlWPFWindow.CurrentSettings.WindowClickThrough ? 1 : 0,
                                            ControlWPFWindow.CurrentSettings.HideBorder ? 1 : 0
                                            ));

            //送信
            uClient?.Send(infoBundle);

            //【イベント送信】VRM基本情報(VRM information) [独立送信](大きいため単独で送る)
            if (vrmdata != null)
            {
                //ファイルパス, キャラ名
                uClient?.Send(new uOSC.Message("/VMC/Ext/VRM", vrmdata.FilePath, vrmdata.Title));
            }
            else if (string.IsNullOrEmpty(remoteName) == false)
            {
                uClient?.Send(new uOSC.Message("/VMC/Ext/Remote", remoteName, remoteJson));
            }

            //【イベント送信】設定ファイルパス(Loaded config path) [独立送信](大きいため単独で送る)
            if (window != null)
            {
                //ファイルパス, キャラ名
                uClient?.Send(new uOSC.Message("/VMC/Ext/Config", window.lastLoadedConfigPath));
            }

            //【イベント送信】Option文字列(Option string) [独立送信](大きいため単独で送る)
            uClient?.Send(new uOSC.Message("/VMC/Ext/Opt", optionString));
        }
    }
    void LateUpdate()
    {
        uClient.Clear();
        bundle = new Bundle();
        if (Model == null)
        {
            Animator[] avatars = FindObjectsOfType <Animator>();
            if (avatars.Length > 1)
            {
                if (error != null)
                {
                    error.text = "Error: Please only put one avatar into the scene.";
                }
                return;
            }
            else if (avatars.Length == 0)
            {
                if (error != null)
                {
                    error.text = "Error: Please put exactly one avatar into the scene.";
                }
                return;
            }
            if (error != null)
            {
                error.text = null;
            }
            Model = avatars[0].gameObject;

            modelPos = Model.transform.position;
            modelRot = Model.transform.rotation;
            if (animator)
            {
                Transform hips = animator.GetBoneTransform(HumanBodyBones.Hips);
                if (hips != null)
                {
                    hipsPos         = hips.position;
                    hipsPosLocal    = hips.localPosition;
                    hipsRot         = hips.rotation;
                    hipsRotLocalInv = Quaternion.Inverse(hips.localRotation);
                }
            }
        }

        //モデルが更新されたときのみ読み込み
        if (Model != null && OldModel != Model)
        {
            animator        = Model.GetComponent <Animator>();
            blendShapeProxy = Model.GetComponent <VRMBlendShapeProxy>();
            OldModel        = Model;
        }

        if (Model != null && animator != null && uClient != null)
        {
            //Root
            var     RootTransform = Model.transform;
            Vector3 pos           = RootTransform.position;
            if (RootTransform != null)
            {
                SendVMC("/VMC/Ext/Root/Pos",
                        "root",
                        pos.x, pos.y, pos.z,
                        RootTransform.rotation.x, RootTransform.rotation.y, RootTransform.rotation.z, RootTransform.rotation.w);
            }

            //Bones
            foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones)))
            {
                if (bone != HumanBodyBones.LastBone)
                {
                    var Transform = animator.GetBoneTransform(bone);
                    if (Transform != null)
                    {
                        Vector3    position = Transform.localPosition;
                        Quaternion rotation = Transform.localRotation;

                        if (bone == HumanBodyBones.Hips)
                        {
                            // Calculate a positional offset for the hips that includes the movement of transforms between the model root and the hips, but excludes the movement of the root
                            // First move the root back to its original position
                            Vector3 rootPos = Model.transform.position;
                            Model.transform.position = modelPos;
                            // Move the hips to its original absolute position
                            Transform.position = hipsPos;
                            // Get its local position, which will be offset by the cumulative offsets of intermediate transforms
                            Vector3 localHipsOrig = Transform.localPosition;
                            // Restore the positions of hips and root
                            Transform.localPosition  = position;
                            Model.transform.position = rootPos;
                            // Subtract the local position offset
                            position -= localHipsOrig - hipsPosLocal;

                            // Do the same thing for rotation
                            // First turn the root back to its original rotation
                            Quaternion rootRot = Model.transform.rotation;
                            Model.transform.rotation = modelRot;
                            // Return the hips to its original absolute rotation
                            Transform.rotation = hipsRot;
                            // Get its local rotation, which will be rotated by the cumulative rotations of intermediate transforms
                            Quaternion localHipsRotOrig = Transform.localRotation;
                            // Restore the rotations of hips and root
                            Transform.localRotation  = rotation;
                            Model.transform.rotation = rootRot;
                            // Inverse rotate the local rotation difference
                            rotation = rotation * Quaternion.Inverse(localHipsRotOrig * hipsRotLocalInv);
                        }

                        SendVMC("/VMC/Ext/Bone/Pos",
                                bone.ToString(),
                                position.x, position.y, position.z,
                                rotation.x, rotation.y, rotation.z, rotation.w);
                    }
                }
            }

            //ボーン位置を仮想トラッカーとして送信
            SendBoneTransformForTracker(HumanBodyBones.Head, "Head");
            SendBoneTransformForTracker(HumanBodyBones.Spine, "Spine");
            SendBoneTransformForTracker(HumanBodyBones.LeftHand, "LeftHand");
            SendBoneTransformForTracker(HumanBodyBones.RightHand, "RightHand");
            SendBoneTransformForTracker(HumanBodyBones.LeftFoot, "LeftFoot");
            SendBoneTransformForTracker(HumanBodyBones.RightFoot, "RightFoot");

            //BlendShape
            if (blendShapeProxy != null)
            {
                foreach (var b in blendShapeProxy.GetValues())
                {
                    SendVMC("/VMC/Ext/Blend/Val",
                            b.Key.ToString(),
                            (float)b.Value
                            );
                }
                SendVMC("/VMC/Ext/Blend/Apply");
            }

            //Available
            SendVMC("/VMC/Ext/OK", 1);
            SendVMC("/VMC/Ext/T", Time.time);
            if (sendBundle)
            {
                uClient.Send(bundle);
            }
        }
        else
        {
            SendVMC("/VMC/Ext/OK", 0);
            SendVMC("/VMC/Ext/T", Time.time);
            if (sendBundle)
            {
                uClient.Send(bundle);
            }
        }
    }
Exemple #3
0
    //基本的に毎フレーム送信するもの
    void SendPerFrame()
    {
        uOSC.Bundle rootBundle = new uOSC.Bundle(uOSC.Timestamp.Immediate);

        if (CurrentModel != null && animator != null)
        {
            //Root
            if (vrik == null)
            {
                vrik = CurrentModel.GetComponent <VRIK>();
                Debug.Log("ExternalSender: VRIK Updated");
            }

            if (frameOfRoot > periodRoot && periodRoot != 0)
            {
                frameOfRoot = 1;
                if (vrik != null)
                {
                    var RootTransform = vrik.references.root;
                    var offset        = handTrackerRoot.transform;
                    if (RootTransform != null && offset != null)
                    {
                        rootBundle.Add(new uOSC.Message("/VMC/Ext/Root/Pos",
                                                        "root",
                                                        RootTransform.position.x, RootTransform.position.y, RootTransform.position.z,
                                                        RootTransform.rotation.x, RootTransform.rotation.y, RootTransform.rotation.z, RootTransform.rotation.w,
                                                        offset.localScale.x, offset.localScale.y, offset.localScale.z,
                                                        offset.position.x, offset.position.y, offset.position.z));
                    }
                }
            }
            frameOfRoot++;

            //Bones
            if (frameOfBone > periodBone && periodBone != 0)
            {
                frameOfBone = 1;

                uOSC.Bundle boneBundle = new uOSC.Bundle(uOSC.Timestamp.Immediate);
                int         cnt        = 0;//パケット分割カウンタ

                foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones)))
                {
                    if (bone == HumanBodyBones.LastBone)
                    {
                        continue;
                    }

                    var Transform = animator.GetBoneTransform(bone);
                    if (Transform != null)
                    {
                        boneBundle.Add(new uOSC.Message("/VMC/Ext/Bone/Pos",
                                                        bone.ToString(),
                                                        Transform.localPosition.x, Transform.localPosition.y, Transform.localPosition.z,
                                                        Transform.localRotation.x, Transform.localRotation.y, Transform.localRotation.z, Transform.localRotation.w));

                        cnt++;
                        //1200バイトを超えない程度に分割する
                        if (cnt > PACKET_DIV_BONE)
                        {
                            uClient?.Send(boneBundle);
                            boneBundle = new uOSC.Bundle(uOSC.Timestamp.Immediate);
                            cnt        = 0;
                        }
                    }
                }
                //余ったボーンは雑多な情報と共に送る
                rootBundle.Add(boneBundle);
            }
            frameOfBone++;

            //Blendsharp
            if (blendShapeProxy == null)
            {
                blendShapeProxy = CurrentModel.GetComponent <VRMBlendShapeProxy>();
                Debug.Log("ExternalSender: VRMBlendShapeProxy Updated");
            }

            if (frameOfBlendShape > periodBlendShape && periodBlendShape != 0)
            {
                frameOfBlendShape = 1;

                uOSC.Bundle blendShapeBundle = new uOSC.Bundle(uOSC.Timestamp.Immediate);
                if (blendShapeProxy != null)
                {
                    foreach (var b in blendShapeProxy.GetValues())
                    {
                        blendShapeBundle.Add(new uOSC.Message("/VMC/Ext/Blend/Val",
                                                              b.Key.ToString(),
                                                              (float)b.Value
                                                              ));
                    }
                    blendShapeBundle.Add(new uOSC.Message("/VMC/Ext/Blend/Apply"));
                }
                uClient?.Send(blendShapeBundle);
            }
            frameOfBlendShape++;
        }

        //Camera
        if (frameOfCamera > periodCamera && periodCamera != 0)
        {
            frameOfCamera = 1;
            if (currentCamera != null)
            {
                rootBundle.Add(new uOSC.Message("/VMC/Ext/Cam",
                                                "Camera",
                                                currentCamera.transform.position.x, currentCamera.transform.position.y, currentCamera.transform.position.z,
                                                currentCamera.transform.rotation.x, currentCamera.transform.rotation.y, currentCamera.transform.rotation.z, currentCamera.transform.rotation.w,
                                                currentCamera.fieldOfView));
            }
        }
        frameOfCamera++;

        //TrackerSend
        if (frameOfDevices > periodDevices && periodDevices != 0)
        {
            frameOfDevices = 1;

            rootBundle.Add(new uOSC.Message("/VMC/Ext/Hmd/Pos",
                                            trackerHandler.HMDObject.name,
                                            trackerHandler.HMDObject.transform.position.x, trackerHandler.HMDObject.transform.position.y, trackerHandler.HMDObject.transform.position.z,
                                            trackerHandler.HMDObject.transform.rotation.x, trackerHandler.HMDObject.transform.rotation.y, trackerHandler.HMDObject.transform.rotation.z, trackerHandler.HMDObject.transform.rotation.w));
            rootBundle.Add(new uOSC.Message("/VMC/Ext/Hmd/Pos/Local",
                                            trackerHandler.HMDObject.name,
                                            trackerHandler.HMDObject.transform.localPosition.x, trackerHandler.HMDObject.transform.localPosition.y, trackerHandler.HMDObject.transform.localPosition.z,
                                            trackerHandler.HMDObject.transform.localRotation.x, trackerHandler.HMDObject.transform.localRotation.y, trackerHandler.HMDObject.transform.localRotation.z, trackerHandler.HMDObject.transform.localRotation.w));

            foreach (var c in trackerHandler.Controllers)
            {
                rootBundle.Add(new uOSC.Message("/VMC/Ext/Con/Pos",
                                                c.name,
                                                c.transform.position.x, c.transform.position.y, c.transform.position.z,
                                                c.transform.rotation.x, c.transform.rotation.y, c.transform.rotation.z, c.transform.rotation.w));
                rootBundle.Add(new uOSC.Message("/VMC/Ext/Con/Pos/Local",
                                                c.name,
                                                c.transform.localPosition.x, c.transform.localPosition.y, c.transform.localPosition.z,
                                                c.transform.localRotation.x, c.transform.localRotation.y, c.transform.localRotation.z, c.transform.localRotation.w));
            }
            foreach (var c in trackerHandler.Trackers)
            {
                rootBundle.Add(new uOSC.Message("/VMC/Ext/Tra/Pos",
                                                c.name,
                                                c.transform.position.x, c.transform.position.y, c.transform.position.z,
                                                c.transform.rotation.x, c.transform.rotation.y, c.transform.rotation.z, c.transform.rotation.w));
                rootBundle.Add(new uOSC.Message("/VMC/Ext/Tra/Pos/Local",
                                                c.name,
                                                c.transform.localPosition.x, c.transform.localPosition.y, c.transform.localPosition.z,
                                                c.transform.localRotation.x, c.transform.localRotation.y, c.transform.localRotation.z, c.transform.localRotation.w));
            }
        }
        frameOfDevices++;



        //Status
        if (frameOfStatus > periodStatus && periodStatus != 0)
        {
            frameOfStatus = 1;
            int available = 0;
            if (CurrentModel != null && animator != null)
            {
                //Available
                available = 1;
            }
            if (window != null)
            {
                rootBundle.Add(new uOSC.Message("/VMC/Ext/OK", (int)available, (int)window.calibrationState, (int)window.lastCalibrateType));
            }
            rootBundle.Add(new uOSC.Message("/VMC/Ext/T", Time.time));
        }
        frameOfStatus++;

        uClient?.Send(rootBundle);

        //---End of frame---
    }