public override void Send() { if (_model != null && animator != null && _client != null) { _client.Send("/VMC/Ext/Root/Pos", "root", _model.transform.position.x, _model.transform.position.y, _model.transform.position.z, _model.transform.rotation.x, _model.transform.rotation.y, _model.transform.rotation.z, _model.transform.rotation.w); //Bones foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones))) { if (bone != HumanBodyBones.LastBone) { var Transform = animator.GetBoneTransform(bone); if (Transform != null) { _client.Send("/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); } } } if (blendShapeProxy != null) { foreach (var b in blendShapeProxy.GetValues()) { _client.Send("/VMC/Ext/Blend/Val", b.Key.ToString(), (float)b.Value ); } _client.Send("/VMC/Ext/Blend/Apply"); } _client.Send("/VMC/Ext/OK", 1); } else { _client.Send("/VMC/Ext/OK", 0); } _client.Send("/VMC/Ext/T", Time.time); }
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); } } }
// Update is called once per frame void Update() { 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) { uClient?.Send("/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; foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones))) { var Transform = animator.GetBoneTransform(bone); if (Transform != null) { uClient?.Send("/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); } } } frameOfBone++; //Blendsharp if (blendShapeProxy == null) { blendShapeProxy = CurrentModel.GetComponent <VRMBlendShapeProxy>(); Debug.Log("ExternalSender: VRMBlendShapeProxy Updated"); } if (frameOfBlendShape > periodBlendShape && periodBlendShape != 0) { frameOfBlendShape = 1; if (blendShapeProxy != null) { foreach (var b in blendShapeProxy.GetValues()) { uClient?.Send("/VMC/Ext/Blend/Val", b.Key.ToString(), (float)b.Value ); } uClient?.Send("/VMC/Ext/Blend/Apply"); } } frameOfBlendShape++; } //Camera if (frameOfCamera > periodCamera && periodCamera != 0) { frameOfCamera = 1; if (currentCamera != null) { uClient?.Send("/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; uClient?.Send("/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); uClient?.Send("/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) { uClient?.Send("/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); uClient?.Send("/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) { uClient?.Send("/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); uClient?.Send("/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; if (CurrentModel != null && animator != null) { //Available uClient?.Send("/VMC/Ext/OK", 1); } else { uClient?.Send("/VMC/Ext/OK", 0); } uClient?.Send("/VMC/Ext/T", Time.time); } frameOfStatus++; //---End of frame--- }
//基本的に毎フレーム送信するもの 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; var hmdTrackingPoint = TrackingPointManager.Instance.GetHmdTrackingPoint(); if (hmdTrackingPoint != null) { rootBundle.Add(new uOSC.Message("/VMC/Ext/Hmd/Pos", hmdTrackingPoint.Name, hmdTrackingPoint.TargetTransform.position.x, hmdTrackingPoint.TargetTransform.position.y, hmdTrackingPoint.TargetTransform.position.z, hmdTrackingPoint.TargetTransform.rotation.x, hmdTrackingPoint.TargetTransform.rotation.y, hmdTrackingPoint.TargetTransform.rotation.z, hmdTrackingPoint.TargetTransform.rotation.w)); rootBundle.Add(new uOSC.Message("/VMC/Ext/Hmd/Pos/Local", hmdTrackingPoint.Name, hmdTrackingPoint.TargetTransform.localPosition.x, hmdTrackingPoint.TargetTransform.localPosition.y, hmdTrackingPoint.TargetTransform.localPosition.z, hmdTrackingPoint.TargetTransform.localRotation.x, hmdTrackingPoint.TargetTransform.localRotation.y, hmdTrackingPoint.TargetTransform.localRotation.z, hmdTrackingPoint.TargetTransform.localRotation.w)); } foreach (var c in TrackingPointManager.Instance.GetControllerTrackingPoints()) { rootBundle.Add(new uOSC.Message("/VMC/Ext/Con/Pos", c.Name, c.TargetTransform.position.x, c.TargetTransform.position.y, c.TargetTransform.position.z, c.TargetTransform.rotation.x, c.TargetTransform.rotation.y, c.TargetTransform.rotation.z, c.TargetTransform.rotation.w)); rootBundle.Add(new uOSC.Message("/VMC/Ext/Con/Pos/Local", c.Name, c.TargetTransform.localPosition.x, c.TargetTransform.localPosition.y, c.TargetTransform.localPosition.z, c.TargetTransform.localRotation.x, c.TargetTransform.localRotation.y, c.TargetTransform.localRotation.z, c.TargetTransform.localRotation.w)); } foreach (var c in TrackingPointManager.Instance.GetTrackerTrackingPoints()) { rootBundle.Add(new uOSC.Message("/VMC/Ext/Tra/Pos", c.Name, c.TargetTransform.position.x, c.TargetTransform.position.y, c.TargetTransform.position.z, c.TargetTransform.rotation.x, c.TargetTransform.rotation.y, c.TargetTransform.rotation.z, c.TargetTransform.rotation.w)); rootBundle.Add(new uOSC.Message("/VMC/Ext/Tra/Pos/Local", c.Name, c.TargetTransform.localPosition.x, c.TargetTransform.localPosition.y, c.TargetTransform.localPosition.z, c.TargetTransform.localRotation.x, c.TargetTransform.localRotation.y, c.TargetTransform.localRotation.z, c.TargetTransform.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--- }
void Update() { //モデルが更新されたときのみ読み込み 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; if (RootTransform != null) { uClient.Send("/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); } //Bones var boneBundle = new Bundle(Timestamp.Now); foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones))) { if (bone != HumanBodyBones.LastBone) { var Transform = animator.GetBoneTransform(bone); if (Transform != null) { boneBundle.Add(new 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)); } } } uClient.Send(boneBundle); //ボーン位置を仮想トラッカーとして送信 var trackerBundle = new Bundle(Timestamp.Now); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.Head, "Head"); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.Spine, "Spine"); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.LeftHand, "LeftHand"); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.RightHand, "RightHand"); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.LeftFoot, "LeftFoot"); SendBoneTransformForTracker(ref trackerBundle, HumanBodyBones.RightFoot, "RightFoot"); uClient.Send(trackerBundle); //BlendShape if (blendShapeProxy != null) { var blendShapeBundle = new Bundle(Timestamp.Now); foreach (var b in blendShapeProxy.GetValues()) { blendShapeBundle.Add(new Message("/VMC/Ext/Blend/Val", b.Key.ToString(), (float)b.Value )); } blendShapeBundle.Add(new Message("/VMC/Ext/Blend/Apply")); uClient.Send(blendShapeBundle); } //Available uClient.Send("/VMC/Ext/OK", 1); } else { uClient.Send("/VMC/Ext/OK", 0); } uClient.Send("/VMC/Ext/T", Time.time); }
void OnGUI() { if (!Application.isEditor || !enablePreview) { return; } if (!hadEnabled) { hadEnabled = true; EnablePreview(); return; } bool clicked = false; scrollViewVector = GUI.BeginScrollView(new Rect(0, 0, 116, Screen.height), scrollViewVector, new Rect(0, 0, 100, proxy.BlendShapeAvatar.Clips.Count * 23 + 23)); if (GUI.Button(new Rect(0, 0, 100, 22), "[Hide]")) { enablePreview = false; hadEnabled = false; return; } int k = 1; foreach (var values in proxy.GetValues()) { if (GUI.Button(new Rect(0, 23 * k, 100, 22), values.Key.Name)) { currentExpression = values.Key.Name; blendShapeKey = values.Key; clicked = true; } k++; } GUI.EndScrollView(); if (clicked) { foreach (var values in proxy.GetValues()) { if (blendShapeKey.Name.ToUpper() == values.Key.Name.ToUpper()) { proxy.ImmediatelySetValue(values.Key, 1f); } else { proxy.ImmediatelySetValue(values.Key, 0f); } } mixer.SetInputWeight(0, 1); for (int i = 0; i < animations.Length; i++) { if (animations[i].blendshapeName.ToUpper() == currentExpression.ToUpper()) { if (toGraph[i] > -1) { mixer.SetInputWeight(toGraph[i], 1); mixer.GetInput(toGraph[i]).SetTime(0); } if (animations[i].animation != null && animations[i].animation.humanMotion) { mixer.SetInputWeight(0, 0); } } else { if (toGraph[i] > -1) { mixer.SetInputWeight(toGraph[i], 0); } } } } }