public void Callback(TBody tbody) { TBody that = tbody; if (that.trsHead == null) { return; } CameraMain mainCamera = GameMain.Instance.MainCamera; if (mainCamera == null) { return; } try { bool bParamHeadTrack = false; Maid maid = tbody.maid; if (maid != null) { bParamHeadTrack = ExSaveData.GetBool(maid, PluginName, "HEAD_TRACK", false); } Vector3 thatHeadEulerAngle = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngle"); Vector3 thatHeadEulerAngleG = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngleG"); Vector3 thatEyeEulerAngle = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "EyeEulerAngle"); if (bParamHeadTrack) { ExternalValues externalValues = PluginHelper.GetOrAddComponent<ExternalValues>(tbody.gameObject); externalValues.tbody = tbody; newTbodyMoveHeadAndEyeCallback2(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle); } else { originalTbodyMoveHeadAndEyeCallback2(tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle); } Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngle", thatHeadEulerAngle); Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngleG", thatHeadEulerAngleG); Helper.SetInstanceField(typeof(TBody), that, "EyeEulerAngle", thatEyeEulerAngle); } catch (Exception ex) { Helper.ShowException(ex); } }
public static string htmlUC_TheoDoiPhieuThu(DataTable table) { string html = "<table border='1' style='border-collapse:collapse; width:100%;'>"; html += THead.TheoDoiPhieuThu(); #region tbody List <string> tenCot = new List <string>() { "stt", "Hoten", "rong", "tienchithangtruoc", "rong", "tientruthangtruoc", "TienAn", "HocPhi", "PVBT", "AnSang", "VeSinh", "tongthu", "ngayHoanTien", "sohoadon" }; html += TBody.Fill(tenCot, table); #endregion html += "</table>"; return(html); }
public void Callback(TBody tbody) { TBody that = tbody; if (that.trsHead == null) { return; } CameraMain mainCamera = GameMain.Instance.MainCamera; if (mainCamera == null) { return; } try { bool bParamHeadTrack = false; Maid maid = tbody.maid; if (maid != null) { bParamHeadTrack = ExSaveData.GetBool(maid, PluginName, "HEAD_TRACK", false); } Vector3 thatHeadEulerAngle = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngle"); Vector3 thatHeadEulerAngleG = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngleG"); Vector3 thatEyeEulerAngle = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "EyeEulerAngle"); if (bParamHeadTrack) { ExternalValues externalValues = PluginHelper.GetOrAddComponent <ExternalValues>(tbody.gameObject); externalValues.tbody = tbody; newTbodyMoveHeadAndEyeCallback2(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle); } else { originalTbodyMoveHeadAndEyeCallback2(tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle); } Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngle", thatHeadEulerAngle); Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngleG", thatHeadEulerAngleG); Helper.SetInstanceField(typeof(TBody), that, "EyeEulerAngle", thatEyeEulerAngle); } catch (Exception ex) { Helper.ShowException(ex); } }
public void Init(Transform[] boneList, TBody b, float[,] initConstrait, Transform initRoroot = null) { this.body = b; this.defLENroot = (boneList[0].position - boneList[1].position).magnitude; this.defLENhead = (boneList[2].position - boneList[1].position).magnitude; this.mid_old = boneList[1].position; this.defRootlocalRotation = boneList[0].localRotation; this.defMidlocalRotation = boneList[1].localRotation; this.vechand = Vector3.zero; if (initRoroot != null) { this.defLENroroot = (initRoroot.position - boneList[0].position).magnitude; this.defRorootlocalRotation = initRoroot.localRotation; } this.constrait = initConstrait; }
public static void FaceTypeHook(TBody self, ref string slotname, ref int matno, ref string prop_name, ref string filename, ref Dictionary <string, byte[]> dicModTexData, ref MaidParts.PARTS_COLOR f_ePartsColorId) { int num = (int)TBody.hashSlotName[slotname]; TBodySkin tBodySkin = self.goSlot[num]; string modelname = (Path.GetFileNameWithoutExtension(tBodySkin.m_strModelFileName)); int start = modelname.IndexOf("facetype"); if (slotname == "head" && start != -1 && filename.IndexOf("*") != -1) { if (!GameUty.FileSystemMod.IsExistentFile(filename.Replace("*", tBodySkin.m_strModelFileName))) { string type = modelname.Substring(start + 8, 3); filename = filename.Replace("*", "face" + type); } } }
public MaidTransforms(TBody body) { Body = body.GetBone("Bip01"); FootL = body.GetBone("Bip01 L Foot"); FootR = body.GetBone("Bip01 R Foot"); ToesL = new[] { CMT.SearchObjName(FootL, "Bip01 L Toe0"), CMT.SearchObjName(FootL, "Bip01 L Toe1"), CMT.SearchObjName(FootL, "Bip01 L Toe2"), }; ToesR = new[] { CMT.SearchObjName(FootR, "Bip01 R Toe0"), CMT.SearchObjName(FootR, "Bip01 R Toe1"), CMT.SearchObjName(FootR, "Bip01 R Toe2"), }; }
Vector3 updateEyeTargetPos(TBody tbody) { TBody that = tbody; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTargetWorldPos:ワールド座標系での視線のターゲット位置 Vector3 eyeTargetWorldPos; if (that.trsLookTarget == null) { eyeTargetWorldPos = that.trsHead.TransformPoint(that.offsetLookTarget); if (that.boEyeSorashi) { // num : 顔の前方と顔→カメラベクトルの内積。1.0に近ければ、カメラが顔の正面にある float num = Vector3.Dot( (eyeTargetWorldPos - that.trsHead.position).normalized, (mainCamera.transform.position - that.trsHead.position).normalized); if (that.EyeSorashiCnt > 0) { ++that.EyeSorashiCnt; if (that.EyeSorashiCnt > 200) { that.EyeSorashiCnt = 0; } } // カメラが顔の前方にあり、なおかつ前回の変更から 200 フレーム経過しているなら、新しい「前方」を決める if (num > 0.9f && that.EyeSorashiCnt == 0) { that.offsetLookTarget = !that.EyeSorashiTgl ? new Vector3(-0.6f, 1f, 0.6f) : new Vector3(-0.5f, 1f, -0.7f); that.EyeSorashiTgl = !that.EyeSorashiTgl; that.EyeSorashiCnt = 1; } } } else { eyeTargetWorldPos = that.trsLookTarget.position; } return(eyeTargetWorldPos); }
void InitKinectObject(TBody maidBody, Vector3 startingPosition) { kinectPosition = new GameObject(); kinectPosition.transform.position = startingPosition; var kinectCube = GameObject.CreatePrimitive(PrimitiveType.Cube); kinectCube.transform.SetParent(kinectPosition.transform); kinectCube.transform.localPosition = Vector3.zero; kinectCube.transform.localScale = 0.1f * Vector3.one; foreach (var value in Enum.GetValues(typeof(BodyJointType))) { var o = new GameObject(); /*GameObject.CreatePrimitive(PrimitiveType.Sphere);*//*new GameObject($"KinectJoint_{value}");*/ o.transform.SetParent(kinectPosition.transform); //o.transform.localScale = 0.01f * Vector3.one; o.transform.localPosition = 2f * Vector3.forward; var boneDraw = CreateBoneNode($"kinect_{value}"); boneDraw.transform.SetParent(kinectPosition.transform); //boneDraw.transform.localPosition += Vector3.forward * 2f; bodyJoints[(BodyJointType)value] = o.transform; bodyJointGizmos[(BodyJointType)value] = boneDraw.transform; } var gizmo = kinectPosition.AddComponent <GizmoRender>(); gizmo.eAxis = true; gizmo.eRotate = true; gizmo.offsetScale = 0.5f; gizmo.Visible = true; foreach (var jointType in maidBodyToKinectJointsDict) { maidJoints.Add(jointType.Value, maidBody.GetBone(jointType.Key)); } bipJoint = maidBody.GetBone("Bip01"); foreach (var keyValuePair in maidJoints) { Log($"{keyValuePair.Value.name}: Local pos: {keyValuePair.Value.localPosition}; Local rot: {keyValuePair.Value.localRotation}"); } }
void Update() { if (Application.loadedLevel != 5) { return; } if (editViewReset == null) { editViewReset = UnityEngine.Object.FindObjectOfType <EditViewReset>(); } if (sceneEdit == null) { sceneEdit = UnityEngine.Object.FindObjectOfType <SceneEdit>(); } if (editViewReset != null && sceneEdit != null) { Maid maid = GameMain.Instance.CharacterMgr.GetMaid(0); if (bLevelWasLoaded) { bLevelWasLoaded = false; LoadSettings(maid); } // UICamera.InputEnable が False になるとサムネール撮影用のために着衣状態になる TBody tbody = maid == null ? null : maid.body0; if (tbody != null && fieldInfo_TBody_m_eMaskMode != null && UICamera.InputEnable) { lastMaid = maid; bLastAutoCam = editViewReset.GetVisibleAutoCam(); bLastEyeToCam = editViewReset.GetVisibleEyeToCam(); lastBgName = GameMain.Instance.BgMgr.GetBGName(); lastClothMaskMode = (TBody.MaskMode)fieldInfo_TBody_m_eMaskMode.GetValue(tbody); lastPoseName = tbody.LastAnimeFN; lastCameraPos = mainCamera.GetPos(); lastCameraTargetPos = mainCamera.GetTargetPos(); lastCameraDistance = mainCamera.GetDistance(); lastCameraRotation = Camera.main.gameObject.transform.rotation; lastCameraFov = Camera.main.fieldOfView; } } }
public override bool IKCmoUpdate(TBody body, Transform trh, Vector3 offset, string hand = "右手") { var ctrl = body.IKCtrl.GetIKData(hand, IKBend); /*ctrl.MyIKCtrl.GetType().GetProperty("IsUpdateEnd").SetValue(ctrl.MyIKCtrl, true, null); * ctrl.MyIKCtrl.IsUpdateLate = false; * ctrl.ApplyIKSetting(); */ Vector3 pos = Vector3.zero; Quaternion rot = Quaternion.identity; bool proc = GetIKCmoPosRot(body, out pos, out rot, hand); if (proc) { ctrl.IKCmo.Porc(trh.parent.parent, trh.parent, trh, pos, rot * offset, ctrl); return(true); } return(false); }
public override bool IKCmoUpdate(TBody body, Transform trh, Vector3 offset, string hand = "右手") { Vector3 pos = Vector3.zero; Quaternion rot = Quaternion.identity; bool proc = GetIKCmoPosRot(body, out pos, out rot, hand); var mgr = body.IKHandR; if (hand != "右手") { mgr = body.IKHandL; } if (proc) { mgr.IKCmo.Porc(trh.parent.parent, trh.parent, trh, pos, rot * offset); return(true); } return(false); }
public static string htmlUC_PhieuCho(string tenNhomTre, DataTable table) { string html = "<table border='1' style='border-collapse:collapse; width:100%;'>"; html += THead.PhieuCho(tenNhomTre); #region tbody List <string> tenCot = new List <string>() { "stt", "tendaydu", "tendonvitinh", "CT.giatien", "soluonggam", "tienmotthucpham" }; html += TBody.Fill(tenCot, table); #endregion html += "</table>"; return(html); }
public void SetValue(TBody body) { var dtime = DateTime.FromOADate(body.time); Issi = Enumerable.Repeat('\0', 20).ToArray(); var sourcearray = body.GetIssi().ToArray(); Array.Copy(sourcearray, Issi, sourcearray.Length); Lon = body.lon; Lat = body.lat; Speed = (ushort)body.speed; Dir = (ushort)body.dir; Height = (ushort)body.height; Precision = 0; Year = Convert.ToUInt16(dtime.Year); Month = Convert.ToByte(dtime.Month); Day = Convert.ToByte(dtime.Day); Hour = Convert.ToByte(dtime.Hour); Minute = Convert.ToByte(dtime.Minute); Second = Convert.ToByte(dtime.Second); }
public static string htmlUC_ThucDonTuan(DataTable table) { string html = "<table border='1' style='border-collapse:collapse; width:100%;'>"; html += THead.ThucDonTuan(); #region tbody List <string> tenCot = new List <string>() { "thu_ngay", "Bửa sáng", "Bửa trưa", "Bửa xế", "Bửa phụ" }; html += TBody.Fill(tenCot, table); #endregion html += "</table>"; return(html); }
public override object GetIkPoint(TBody body, string hand = "右手") { #if DEBUG if (Input.GetKey(KeyCode.Space)) { IKBend = true; Console.WriteLine("IKBend: ON"); } else { IKBend = false; } #endif var obj = body.IKCtrl.GetIKData(hand, IKBend).GetTargetData(IKCtrlData.IKAttachType.Point); if (obj == null) { obj = body.IKCtrl.GetIKData(hand, IKBend).GetTargetData(IKCtrlData.IKAttachType.NewPoint); } return(obj); }
void DrawBones() { boneObjects.Clear(); maidTransforms.Clear(); var maid = FindObjectOfType <Maid>(); if (maid == null) { return; } maidBody = maid.body0; foreach (var boneName in boneNames) { var bone = maidBody.GetBone(boneName); if (bone == null) { Error($"Bone {boneName} does not exist!"); continue; } var c = Random.ColorHSV(); Log($"Creating node {boneName}"); var go = CreateBoneNode(boneName); go.SetActive(true); /*GameObject.CreatePrimitive(PrimitiveType.Cube);*/ //go.GetComponent<Renderer>().material = new Material(Shader.Find("Transparent/Diffuse")) {color = c}; //go.transform.position = bone.position - 2.0f * Vector3.left; //go.transform.localRotation = Quaternion.identity; //go.transform.localScale = 0.05f * Vector3.one; //go.SetActive(true); maidTransforms.Add(bone.gameObject); boneObjects.Add(new KeyValuePair <string, GameObject>(boneName, go)); } }
public static string htmlUC_STTTTheoNgay(DataTable table) { string html = "<table border='1' style='border-collapse:collapse; width:100%;'>"; html += THead.STTTTheoNgay(); #region tbody List <string> tenCot = new List <string>() { "stt", "ngaythanhtoan", "tongsotre", "tienan", "hocphi", "bantruphi", "tienansang", "tienvesinh", "tongthu" }; html += TBody.Fill(tenCot, table); #endregion html += "</table>"; return(html); }
public void SetValue(TBody body) { Issi = Enumerable.Repeat <Byte>(0x25, 20).ToArray(); var bodyssi = body.GetASCIIBytes(body.GetIssi()); Array.Copy(bodyssi, Issi, bodyssi.Length); //var bodyssi = body.GetASCIIBytes(body.GetIssi()); //Issi = new Byte[20]; //for (var i = 0; i < bodyssi.Length; i++) //{ // Issi[i] = bodyssi[i]; //} //for (var i = bodyssi.Length; i <20 ; i++) //{ // Issi[i] = 0x25; //} CC = 0x26; Time = body.GetASCIIBytes(new DateTime(1899, 12, 30).AddDays(body.time).ToString("yyMMddHHmmss")); Lon = body.lon; Lat = body.lat; Speed = Convert.ToDouble(body.speed); Dir = IPAddress.HostToNetworkOrder(body.dir); }
public static string htmlUC_TheKho(DataTable table) { string html = "<table border='1' style='border-collapse:collapse; width:100%;'>"; html += THead.TheKho(); #region tbody List <string> tenCot = new List <string>() { "Ngày lập", "Số phiếu nhập", "Số phiếu xuất", "Diễn giải", "Số lượng nhập", "Thành tiền nhập", "Số lượng xuất", "Thành tiền xuất", "Số lượng tồn", "Thành tiền tồn" }; html += TBody.Fill(tenCot, table); #endregion html += "</table>"; return(html); }
public TableRowTag AddBodyRow() => TBody.Add <TableRowTag>();
// リップシンク強度指定 void SetLipSyncIntensity(Maid maid, TBody tbody) { if (!ExSaveData.GetBool(maid, PluginName, "LIPSYNC_INTENISTY", false)) { return; } float f1 = Mathf.Clamp01(ExSaveData.GetFloat(maid, PluginName, "LIPSYNC_INTENISTY.value", 1f)); maid.VoicePara_1 = f1 * 0.5f; maid.VoicePara_2 = f1 * 0.074f; maid.VoicePara_3 = f1 * 0.5f; maid.VoicePara_4 = f1 * 0.05f; if (f1 < 0.01f) { maid.voice_ao_f2 = 0; } }
// 顔を常時カメラに向ける void HeadToCam(Maid maid, TBody tbody) { float fHeadToCam = ExSaveData.GetFloat(maid, PluginName, "HEADTOCAM", 0f); if (fHeadToCam < -0.5f) { tbody.boHeadToCam = false; } else if (fHeadToCam > 0.5f) { tbody.boHeadToCam = true; } }
public void SetEditedMaterials(TBody.SlotID slot, List<ACCMaterial> edited) { LogUtil.DebugF("Set edited Materials. slot={0}, edited count={1}", slot, edited.Count); string slotName = slot.ToString(); trgtMenu.InitMaterials(slotName, edited); }
public SlotInfo(TBody.SlotID id, MPN mpn, string displayName, bool enable, bool maskable) { this.Id = id; this.Name = Id.ToString(); this.mpn = mpn; this.DisplayName = displayName; this.LongName = displayName + " [" + Name + "]"; this.no = -1; this.enable = enable; this.maskable = maskable; }
// 新しい MoveHeadAndEye void newTbodyMoveHeadAndEyeCallback2(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle) { TBody that = tbody; Maid maid = tbody.maid; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTarget_world:視線の目標位置(ワールド座標系) Vector3 eyeTarget_world = updateEyeTargetPos(tbody); // HeadToCamPer:最終的に顔がカメラを向く度合い // 0 なら元の頭の向き、1 ならカメラの向き if (that.boHeadToCam) { that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed; } else { that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed; } that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer); that.boChkEye = false; newMoveHead(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTarget_world); externalValues.prevQuat = that.trsHead.rotation; if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null) { return; } that.boChkEye = false; { float paramEyeAng = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f); paramEyeAng = Mathf.Clamp(paramEyeAng, -180f, 180f); float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.speed", 0.05f); float paramInside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.inside", 60f); float paramOutside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.outside", 60f); float paramAbove = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.above", 40f); float paramBelow = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.below", 20f); float paramBehind = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.behind", 170f); float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsx", 0f); float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsy", 0f); Vector3 targetPosition = eyeTarget_world; if (!that.boEyeToCam) { // 視線を正面に戻す eyeTarget_world = that.trsHead.TransformPoint(Vector3.up * 1000.0f); } { Transform trsEye = that.trsEyeL; Quaternion defQuat = that.quaDefEyeL * Quaternion.Euler(paramEyeAng, -paramOfsX, -paramOfsY); Quaternion prevQuat = externalValues.prevLeftEyeQuat; Transform trsParent = trsEye.parent; Quaternion newRotation_world = CalcNewEyeRotation( paramOutside, paramInside, paramBelow, paramAbove, paramBehind, trsParent.rotation, trsEye.position, eyeTarget_world ); Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world; q = Quaternion.Slerp(Quaternion.identity, q, 0.2f); // 眼球モデルの中心に、眼球のトランスフォームの原点が無いため、ごまかしている q = Quaternion.Slerp(prevQuat, q, paramSpeed); prevQuat = q; trsEye.localRotation = q * defQuat; externalValues.prevLeftEyeQuat = prevQuat; } { Transform trsEye = that.trsEyeR; Quaternion defQuat = that.quaDefEyeR * Quaternion.Euler(-paramEyeAng, -paramOfsX, paramOfsY); Quaternion prevQuat = externalValues.prevRightEyeQuat; Transform trsParent = trsEye.parent; Quaternion newRotation_world = CalcNewEyeRotation( paramOutside, paramInside, paramAbove, paramBelow, paramBehind, trsParent.rotation, trsEye.position, eyeTarget_world ); Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world; q = Quaternion.Slerp(Quaternion.identity, q, 0.2f); q = Quaternion.Slerp(prevQuat, q, paramSpeed); prevQuat = q; trsEye.localRotation = q * defQuat; externalValues.prevRightEyeQuat = prevQuat; } } }
void originalMoveHead(TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTargetWorldPos) { TBody that = tbody; // CameraMain mainCamera = GameMain.Instance.MainCamera; // eulerAngles1:顔の正面向きのベクトルから見た、視線ターゲットまでの回転量 Vector3 eulerAngles1; Quaternion quaternion1 = new Quaternion(); { // toDirection1:顔からターゲットを見た向き(顔の座標系) Vector3 toDirection1 = Quaternion.Inverse(that.trsNeck.rotation) * (eyeTargetWorldPos - that.trsNeck.position); // quaternion1:(0,1,0) (顔の正面向きのベクトル) から見たときの、toDirection1 までの回転量 quaternion1.SetFromToRotation(Vector3.up, toDirection1); eulerAngles1 = PluginHelper.NormalizeEulerAngles(quaternion1.eulerAngles); } if (that.boHeadToCamInMode) { // 追従範囲外かどうかを判定 if (-80.0f >= eulerAngles1.x || eulerAngles1.x >= 80.0f || -50.0f >= eulerAngles1.z || eulerAngles1.z >= 60.0f) { that.boHeadToCamInMode = false; } } else { // 追従範囲内かどうかを判定 if (-60.0f < eulerAngles1.x && eulerAngles1.x < 60.0f && -40.0f < eulerAngles1.z && eulerAngles1.z < 50.0f) { that.boHeadToCamInMode = true; } } if (that.boHeadToCamInMode) { // 追従モード that.boChkEye = true; float num = 0.3f; if (eulerAngles1.x > thatHeadEulerAngle.x + 10.0f) { thatHeadEulerAngleG.x += num; } else if (eulerAngles1.x < thatHeadEulerAngle.x - 10.0f) { thatHeadEulerAngleG.x -= num; } else { thatHeadEulerAngleG.x *= 0.95f; } if (eulerAngles1.z > thatHeadEulerAngle.z + 10.0f) { thatHeadEulerAngleG.z += num; } else if (eulerAngles1.z < thatHeadEulerAngle.z - 10.0f) { thatHeadEulerAngleG.z -= num; } else { thatHeadEulerAngleG.z *= 0.95f; } } else { // 自由モード float num = 0.1f; if (0.0f > thatHeadEulerAngle.x + 10.0) { thatHeadEulerAngleG.x += num; } if (0.0f < thatHeadEulerAngle.x - 10.0f) { thatHeadEulerAngleG.x -= num; } if (0.0f > thatHeadEulerAngle.z + 10.0f) { thatHeadEulerAngleG.z += num; } if (0.0f < thatHeadEulerAngle.z - 10.0f) { thatHeadEulerAngleG.z -= num; } } thatHeadEulerAngleG *= 0.95f; thatHeadEulerAngle += thatHeadEulerAngleG; float uScale = 0.4f; that.trsHead.localRotation = Quaternion.Slerp( that.trsHead.localRotation, that.quaDefHead * Quaternion.Euler( thatHeadEulerAngle.x * uScale, 0.0f, thatHeadEulerAngle.z * uScale), UTY.COSS(that.HeadToCamPer)); }
// 新しい MoveHeadAndEye void newTbodyMoveHeadAndEyeCallback2(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle) { TBody that = tbody; Maid maid = tbody.maid; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTarget_world:視線の目標位置(ワールド座標系) Vector3 eyeTarget_world = updateEyeTargetPos(tbody); // HeadToCamPer:最終的に顔がカメラを向く度合い // 0 なら元の頭の向き、1 ならカメラの向き if (that.boHeadToCam) { that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed; } else { that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed; } that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer); that.boChkEye = false; newMoveHead(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTarget_world); externalValues.prevQuat = that.trsHead.rotation; if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null) { return; } that.boChkEye = false; if (that.boEyeToCam) { float paramEyeAng = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f); paramEyeAng = Mathf.Clamp(paramEyeAng, -180f, 180f); float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.speed", 0.05f); float paramInside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.inside", 60f); float paramOutside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.outside", 60f); float paramAbove = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.above", 40f); float paramBelow = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.below", 20f); float paramBehind = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.behind", 170f); float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsx", 0f); float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsy", 0f); Vector3 targetPosition = eyeTarget_world; { Transform trsEye = that.trsEyeL; Quaternion defQuat = that.quaDefEyeL * Quaternion.Euler(paramEyeAng, -paramOfsX, -paramOfsY); Quaternion prevQuat = externalValues.prevLeftEyeQuat; Transform trsParent = trsEye.parent; Quaternion newRotation_world = CalcNewEyeRotation( paramOutside, paramInside, paramBelow, paramAbove, paramBehind, trsParent.rotation, trsEye.position, eyeTarget_world ); Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world; q = Quaternion.Slerp(Quaternion.identity, q, 0.2f); // 眼球モデルの中心に、眼球のトランスフォームの原点が無いため、ごまかしている q = Quaternion.Slerp(prevQuat, q, paramSpeed); prevQuat = q; trsEye.localRotation = q * defQuat; externalValues.prevLeftEyeQuat = prevQuat; } { Transform trsEye = that.trsEyeR; Quaternion defQuat = that.quaDefEyeR * Quaternion.Euler(-paramEyeAng, -paramOfsX, paramOfsY); Quaternion prevQuat = externalValues.prevRightEyeQuat; Transform trsParent = trsEye.parent; Quaternion newRotation_world = CalcNewEyeRotation( paramOutside, paramInside, paramAbove, paramBelow, paramBehind, trsParent.rotation, trsEye.position, eyeTarget_world ); Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world; q = Quaternion.Slerp(Quaternion.identity, q, 0.2f); q = Quaternion.Slerp(prevQuat, q, paramSpeed); prevQuat = q; trsEye.localRotation = q * defQuat; externalValues.prevRightEyeQuat = prevQuat; } } }
public CCSlot(TBody.SlotID id) { this.id = id; }
public void SetValue(TBody cbody) { header.UpSerial(); body.SetValue(cbody); body.Seconds = header.Seconds = Convert.ToInt32(DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds); }
public Renderer GetRenderer(TBody.SlotID slotID) { int slotNo = (int)slotID; return slotNo >= currentMaid.body0.goSlot.Count ? null : GetRenderer(currentMaid.body0.GetSlot(slotNo)); }
public Material[] GetMaterials(TBody.SlotID slotID) { int slotNo = (int)slotID; return slotNo >= currentMaid.body0.goSlot.Count ? EmptyList : GetMaterials(currentMaid.body0.GetSlot(slotNo)); }
// スライダー範囲を拡大 void WideSlider(Maid maid) { if (!ExSaveData.GetBool(maid, PluginName, "WIDESLIDER", false)) { return; } TBody tbody = maid.body0; //string[] PropNames = BoneMorph_PropNames; if (tbody == null || tbody.bonemorph == null || tbody.bonemorph.bones == null) { return; } BoneMorph_ boneMorph_ = tbody.bonemorph; // スケール変更するボーンのリスト Dictionary <string, Vector3> boneScale = new Dictionary <string, Vector3>(); // ポジション変更するボーンのリスト Dictionary <string, Vector3> bonePosition = new Dictionary <string, Vector3>(); //この配列に記載があるボーンは頭に影響を与えずにTransformを反映させる。 //ただしボディに繋がっている中のアレは影響を受ける。 string[] ignoreHeadBones = new string[] { "Bip01 Spine1a" }; float eyeAngAngle; float eyeAngX; float eyeAngY; { float ra = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f); float rx = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.x", 0f); float ry = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.y", 0f); rx += -9f; ry += -17f; rx /= 1000f; ry /= 1000f; eyeAngAngle = ra; eyeAngX = rx; eyeAngY = ry; } Vector3 thiScl = new Vector3( 1.0f, ExSaveData.GetFloat(maid, PluginName, "THISCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "THISCL.width", 1f)); Vector3 thiPosL; Vector3 thiPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "THIPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "THIPOS.z", 0f); float dy = 0.0f; thiPosL = new Vector3(dy, dz / 1000f, -dx / 1000f); thiPosR = new Vector3(dy, dz / 1000f, dx / 1000f); } bonePosition["Bip01 L Thigh"] = thiPosL; bonePosition["Bip01 R Thigh"] = thiPosR; Vector3 thi2PosL; Vector3 thi2PosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "THI2POS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "THI2POS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "THI2POS.y", 0f); thi2PosL = new Vector3(dy / 1000f, dz / 1000f, -dx / 1000f); thi2PosR = new Vector3(dy / 1000f, dz / 1000f, dx / 1000f); } bonePosition["Bip01 L Thigh_SCL_"] = thi2PosL; bonePosition["Bip01 R Thigh_SCL_"] = thi2PosR; // 元々足の位置と連動しており、追加するときに整合性を保つため足の位置との和で計算 Vector3 hipPosL; Vector3 hipPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "HIPPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "HIPPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "HIPPOS.z", 0f); hipPosL = new Vector3(dy / 1000f, dz / 1000f, -dx / 1000f); hipPosR = new Vector3(dy / 1000f, dz / 1000f, dx / 1000f); } bonePosition["Hip_L"] = thiPosL + hipPosL; bonePosition["Hip_R"] = thiPosR + hipPosR; Vector3 mtwPosL; Vector3 mtwPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MTWPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MTWPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MTWPOS.z", 0f); mtwPosL = new Vector3(dx / 10f, dy / 10f, dz / 10f); mtwPosR = new Vector3(dx / 10f, dy / 10f, -dz / 10f); } bonePosition["momotwist_L"] = mtwPosL; bonePosition["momotwist_R"] = mtwPosR; Vector3 mmnPosL; Vector3 mmnPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MMNPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MMNPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MMNPOS.z", 0f); mmnPosL = new Vector3(dx / 10f, dy / 10f, dz / 10f); mmnPosR = new Vector3(dx / 10f, -dy / 10f, dz / 10f); } bonePosition["momoniku_L"] = mmnPosL; bonePosition["momoniku_R"] = mmnPosR; Vector3 skirtPos; { float dx = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.z", 0f); skirtPos = new Vector3(-dz / 10f, -dy / 10f, dx / 10f); } bonePosition["Skirt"] = skirtPos; Vector3 spinePos; { float dx = ExSaveData.GetFloat(maid, PluginName, "SPIPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "SPIPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "SPIPOS.z", 0f); spinePos = new Vector3(-dx / 10f, dy / 10f, dz / 10f); } bonePosition["Bip01 Spine"] = spinePos; Vector3 spine0aPos; { float dx = ExSaveData.GetFloat(maid, PluginName, "S0APOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "S0APOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "S0APOS.z", 0f); spine0aPos = new Vector3(-dx / 10f, dy / 10f, dz / 10f); } bonePosition["Bip01 Spine0a"] = spine0aPos; Vector3 spine1Pos; { float dx = ExSaveData.GetFloat(maid, PluginName, "S1POS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "S1POS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "S1POS.z", 0f); spine1Pos = new Vector3(-dx / 10f, dy / 10f, dz / 10f); } bonePosition["Bip01 Spine1"] = spine1Pos; Vector3 spine1aPos; { float dx = ExSaveData.GetFloat(maid, PluginName, "S1APOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "S1APOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "S1APOS.z", 0f); spine1aPos = new Vector3(-dx / 10f, dy / 10f, dz / 10f); } bonePosition["Bip01 Spine1a"] = spine1aPos; Vector3 neckPos; { float dx = ExSaveData.GetFloat(maid, PluginName, "NECKPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "NECKPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "NECKPOS.z", 0f); neckPos = new Vector3(-dx / 10f, dy / 10f, dz / 10f); } bonePosition["Bip01 Neck"] = neckPos; Vector3 clvPosL; Vector3 clvPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "CLVPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "CLVPOS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "CLVPOS.y", 0f); clvPosL = new Vector3(-dx / 10f, dy / 10f, dz / 10f); clvPosR = new Vector3(-dx / 10f, dy / 10f, -dz / 10f); } bonePosition["Bip01 L Clavicle"] = clvPosL; bonePosition["Bip01 R Clavicle"] = clvPosR; Vector3 muneSubPosL; Vector3 muneSubPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.y", 0f); muneSubPosL = new Vector3(-dy / 10f, dz / 10f, -dx / 10f); muneSubPosR = new Vector3(-dy / 10f, -dz / 10f, -dx / 10f); } bonePosition["Mune_L_sub"] = muneSubPosL; bonePosition["Mune_R_sub"] = muneSubPosR; Vector3 munePosL; Vector3 munePosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.y", 0f); munePosL = new Vector3(dz / 10f, -dy / 10f, dx / 10f); munePosR = new Vector3(dz / 10f, -dy / 10f, -dx / 10f); } bonePosition["Mune_L"] = munePosL; bonePosition["Mune_R"] = munePosR; // スケール変更するボーンをリストに一括登録 SetBoneScaleFromList(boneScale, maid, boneAndPropNameList); // 元々尻はPELSCLに連動していたが単体でも設定できるようにする // ただし元との整合性をとるため乗算する Vector3 pelScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "PELSCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "PELSCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "PELSCL.width", 1f)); Vector3 hipScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "HIPSCL.height", 1f) * pelScl.x, ExSaveData.GetFloat(maid, PluginName, "HIPSCL.depth", 1f) * pelScl.y, ExSaveData.GetFloat(maid, PluginName, "HIPSCL.width", 1f) * pelScl.z); boneScale["Hip_L"] = hipScl; boneScale["Hip_R"] = hipScl; Transform tEyePosL = null; Transform tEyePosR = null; float sliderScale = 20f; for (int i = boneMorph_.bones.Count - 1; i >= 0; i--) { BoneMorphLocal boneMorphLocal = boneMorph_.bones[i]; Vector3 scl = new Vector3(1f, 1f, 1f); Vector3 pos = boneMorphLocal.pos; //for (int j = 0; j < (int)PropNames.Length; j++) for (int j = 0; j < BoneMorph.PropNames.Length; j++) { float s = 1f; switch (j) { case 0: s = boneMorph_.SCALE_Kubi; break; case 1: s = boneMorph_.SCALE_Ude; break; case 2: s = boneMorph_.SCALE_EyeX; break; case 3: s = boneMorph_.SCALE_EyeY; break; case 4: s = boneMorph_.Postion_EyeX * (0.5f + boneMorph_.Postion_EyeY * 0.5f); break; case 5: s = boneMorph_.Postion_EyeY; break; case 6: s = boneMorph_.SCALE_HeadX; break; case 7: s = boneMorph_.SCALE_HeadY; break; case 8: s = boneMorph_.SCALE_DouPer; if (boneMorphLocal.Kahanshin == 0f) { s = 1f - s; } break; case 9: s = boneMorph_.SCALE_Sintyou; break; case 10: s = boneMorph_.SCALE_Koshi; break; case 11: s = boneMorph_.SCALE_Kata; break; case 12: s = boneMorph_.SCALE_West; break; default: s = 1f; break; } if ((boneMorphLocal.atr & 1L << (j & 63)) != 0L) { Vector3 v0 = boneMorphLocal.vecs_min[j]; Vector3 v1 = boneMorphLocal.vecs_max[j]; Vector3 n0 = v0 * sliderScale - v1 * (sliderScale - 1f); Vector3 n1 = v1 * sliderScale - v0 * (sliderScale - 1f); float f = (s + sliderScale - 1f) * (1f / (sliderScale * 2.0f - 1f)); scl = Vector3.Scale(scl, Vector3.Lerp(n0, n1, f)); } if ((boneMorphLocal.atr & 1L << (j + 32 & 63)) != 0L) { Vector3 v0 = boneMorphLocal.vecs_min[j + 32]; Vector3 v1 = boneMorphLocal.vecs_max[j + 32]; Vector3 n0 = v0 * sliderScale - v1 * (sliderScale - 1f); Vector3 n1 = v1 * sliderScale - v0 * (sliderScale - 1f); float f = (s + sliderScale - 1f) * (1f / (sliderScale * 2.0f - 1f)); pos = Vector3.Scale(pos, Vector3.Lerp(n0, n1, f)); } } Transform linkT = boneMorphLocal.linkT; if (linkT == null) { continue; } string name = linkT.name; if (name != null && name.Contains("Thigh_SCL_")) { boneMorph_.SnityouOutScale = Mathf.Pow(scl.x, 0.9f); } // リストに登録されているボーンのスケール設定 if (name != null && boneScale.ContainsKey(name)) { scl = Vector3.Scale(scl, boneScale[name]); } // リストに登録されているボーンのポジション設定 if (name != null && bonePosition.ContainsKey(name)) { pos += bonePosition[name]; } Transform muneLParent = f_muneLParent.GetValue(tbody) as Transform; Transform muneLChild = f_muneLChild.GetValue(tbody) as Transform; Transform muneRParent = f_muneRParent.GetValue(tbody) as Transform; Transform muneRChild = f_muneRChild.GetValue(tbody) as Transform; Transform muneLSub = f_muneLSub.GetValue(tbody) as Transform; Transform muneRSub = f_muneRSub.GetValue(tbody) as Transform; if (muneLChild && muneLParent && muneRChild && muneRParent) { muneLChild.localPosition = muneLSub.localPosition; muneLParent.localPosition = muneLSub.localPosition; muneRChild.localPosition = muneRSub.localPosition; muneRParent.localPosition = muneRSub.localPosition; } // ignoreHeadBonesに登録されている場合はヒラエルキーを辿って頭のツリーを無視 if (name != null) { if (!(ignoreHeadBones.Contains(name) && CMT.SearchObjObj(maid.body0.m_Bones.transform.Find("Bip01"), linkT))) { linkT.localScale = scl; } linkT.localPosition = pos; } if (name != null) { if (name == "Eyepos_L") { tEyePosL = linkT; } else if (name == "Eyepos_R") { tEyePosR = linkT; } } } // 目のサイズ・角度変更 // EyeScaleRotate : 目のサイズと角度変更する CM3D.MaidVoicePich.Plugin.cs の追加メソッド // http://pastebin.com/DBuN5Sws // その1>>923 // http://jbbs.shitaraba.net/bbs/read.cgi/game/55179/1438196715/923 if (tEyePosL != null) { Transform linkT = tEyePosL; Vector3 localCenter = linkT.localPosition + (new Vector3(0f, eyeAngY, eyeAngX)); // ローカル座標系での回転中心位置 Vector3 worldCenter = linkT.parent.TransformPoint(localCenter); // ワールド座標系での回転中心位置 Vector3 localAxis = new Vector3(-1f, 0f, 0f); // ローカル座標系での回転軸 Vector3 worldAxis = linkT.TransformDirection(localAxis); // ワールド座標系での回転軸 linkT.localRotation = new Quaternion(-0.00560432f, -0.001345155f, 0.06805823f, 0.9976647f); // 初期の回転量 linkT.RotateAround(worldCenter, worldAxis, eyeAngAngle); } if (tEyePosR != null) { Transform linkT = tEyePosR; Vector3 localCenter = linkT.localPosition + (new Vector3(0f, eyeAngY, -eyeAngX)); // ローカル座標系での回転中心位置 Vector3 worldCenter = linkT.parent.TransformPoint(localCenter); // ワールド座標系での回転中心位置 Vector3 localAxis = new Vector3(-1f, 0f, 0f); // ローカル座標系での回転軸 Vector3 worldAxis = linkT.TransformDirection(localAxis); // ワールド座標系での回転軸 linkT.localRotation = new Quaternion(0.9976647f, 0.06805764f, -0.001350592f, -0.005603582f); // 初期の回転量 linkT.RotateAround(worldCenter, worldAxis, -eyeAngAngle); } // COM3D2追加処理 // ボーンポジション系 var listBoneMorphPos = Helper.GetInstanceField(typeof(BoneMorph_), boneMorph_, "m_listBoneMorphPos"); var ienumPos = listBoneMorphPos as IEnumerable; System.Reflection.Assembly asmPos = System.Reflection.Assembly.GetAssembly(typeof(BoneMorph_)); Type listBoneMorphPosType = listBoneMorphPos.GetType(); Type boneMorphPosType = asmPos.GetType("BoneMorph_+BoneMorphPos"); foreach (object o in ienumPos) { string strPropName = (string)Helper.GetInstanceField(boneMorphPosType, o, "strPropName"); Transform trs = (Transform)Helper.GetInstanceField(boneMorphPosType, o, "trBone"); Vector3 defPos = (Vector3)Helper.GetInstanceField(boneMorphPosType, o, "m_vDefPos"); Vector3 addMin = (Vector3)Helper.GetInstanceField(boneMorphPosType, o, "m_vAddMin"); Vector3 addMax = (Vector3)Helper.GetInstanceField(boneMorphPosType, o, "m_vAddMax"); if (strPropName == "Nosepos") { trs.localPosition = Lerp(addMin, defPos, addMax, (float)boneMorph_.POS_Nose, sliderScale); } else if (strPropName == "MayuY") { trs.localPosition = Lerp(addMin, defPos, addMax, (float)boneMorph_.POS_MayuY, sliderScale); } else if (strPropName == "EyeBallPosYL" || strPropName == "EyeBallPosYR") { trs.localPosition = Lerp(addMin, defPos, addMax, (float)boneMorph_.EyeBallPosY, sliderScale); } else if (strPropName == "Mayupos_L" || strPropName == "Mayupos_R") { Vector3 vector3_1 = Lerp(addMin, defPos, addMax, (float)boneMorph_.POS_MayuY, sliderScale); float x1 = addMin.x; addMin.x = addMax.x; addMax.x = x1; Vector3 vector3_2 = Lerp(addMin, defPos, addMax, (float)boneMorph_.POS_MayuX, sliderScale); float x3 = vector3_2.x + vector3_1.x - defPos.x; trs.localPosition = new Vector3(x3, vector3_1.y, vector3_2.z); } } // ボーンスケール系 var listBoneMorphScl = Helper.GetInstanceField(typeof(BoneMorph_), boneMorph_, "m_listBoneMorphScl"); var ienumScl = listBoneMorphScl as IEnumerable; System.Reflection.Assembly asmScl = System.Reflection.Assembly.GetAssembly(typeof(BoneMorph_)); Type listBoneMorphSclType = listBoneMorphScl.GetType(); Type boneMorphSclType = asmScl.GetType("BoneMorph_+BoneMorphScl"); foreach (object o in ienumScl) { string strPropName = (string)Helper.GetInstanceField(boneMorphSclType, o, "strPropName"); Transform trs = (Transform)Helper.GetInstanceField(boneMorphSclType, o, "trBone"); Vector3 defScl = (Vector3)Helper.GetInstanceField(boneMorphSclType, o, "m_vDefScl"); Vector3 addMin = (Vector3)Helper.GetInstanceField(boneMorphSclType, o, "m_vAddMin"); Vector3 addMax = (Vector3)Helper.GetInstanceField(boneMorphSclType, o, "m_vAddMax"); if (strPropName == "Earscl_L" || strPropName == "Earscl_R") { trs.localScale = Lerp(addMin, defScl, addMax, (float)boneMorph_.SCALE_Ear, sliderScale); } else if (strPropName == "Nosescl") { trs.localScale = Lerp(addMin, defScl, addMax, (float)boneMorph_.SCALE_Nose, sliderScale); } else if (strPropName == "EyeBallSclXL" || strPropName == "EyeBallSclXR") { Vector3 localScale = trs.localScale; localScale.z = Lerp(addMin, defScl, addMax, (float)boneMorph_.EyeBallSclX, sliderScale).z; trs.localScale = localScale; } else if (strPropName == "EyeBallSclYL" || strPropName == "EyeBallSclYR") { Vector3 localScale = trs.localScale; localScale.y = Lerp(addMin, defScl, addMax, (float)boneMorph_.EyeBallSclY, sliderScale).y; trs.localScale = localScale; } } // ボーンローテーション系 var listBoneMorphRot = Helper.GetInstanceField(typeof(BoneMorph_), boneMorph_, "m_listBoneMorphRot"); var ienumRot = listBoneMorphRot as IEnumerable; System.Reflection.Assembly asmRot = System.Reflection.Assembly.GetAssembly(typeof(BoneMorph_)); Type listBoneMorphRotType = listBoneMorphRot.GetType(); Type boneMorphRotType = asmRot.GetType("BoneMorph_+BoneMorphRotatio"); foreach (object o in ienumRot) { string strPropName = (string)Helper.GetInstanceField(boneMorphRotType, o, "strPropName"); Transform trs = (Transform)Helper.GetInstanceField(boneMorphRotType, o, "trBone"); Quaternion defRot = (Quaternion)Helper.GetInstanceField(boneMorphRotType, o, "m_vDefRotate"); Quaternion addMin = (Quaternion)Helper.GetInstanceField(boneMorphRotType, o, "m_vAddMin"); Quaternion addMax = (Quaternion)Helper.GetInstanceField(boneMorphRotType, o, "m_vAddMax"); if (strPropName == "Earrot_L" || strPropName == "Earrot_R") { trs.localRotation = RotLerp(addMin, defRot, addMax, (float)boneMorph_.ROT_Ear, sliderScale); } else if (strPropName == "Mayurot_L" || strPropName == "Mayurot_R") { trs.localRotation = RotLerp(addMin, defRot, addMax, (float)boneMorph_.ROT_Mayu, sliderScale); } } }
// 元の MoveHeadAndEye 相当の処理 void originalTbodyMoveHeadAndEyeCallback2(TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle) { TBody that = tbody; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTargetWorldPos:ワールド座標系での視線のターゲット位置 Vector3 eyeTargetWorldPos = updateEyeTargetPos(tbody); // HeadToCamPer:最終的に顔がカメラを向く度合い // 0 なら元の頭の向き、1 ならカメラの向き if (that.boHeadToCam) { that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed; } else { that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed; } that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer); that.boChkEye = false; originalMoveHead(tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTargetWorldPos); if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null) { return; } // 目の追従処理 if (that.boEyeToCam && that.boChkEye) { Vector3 toDirection2 = Quaternion.Inverse(that.trsHead.rotation) * (eyeTargetWorldPos - that.trsHead.position); Quaternion quaternion2 = new Quaternion(); quaternion2.SetFromToRotation(Vector3.up, toDirection2); Vector3 eulerAngles2 = PluginHelper.NormalizeEulerAngles(quaternion2.eulerAngles); Vector3 view = Vector3.Normalize(eyeTargetWorldPos - that.trsEyeL.position); quaternion2.SetLookRotation(view, Vector3.up); Quaternion quaternion3 = quaternion2 * Quaternion.Euler(0.0f, 90f, 0.0f); float num = 0.5f; if (that.boEyeSorashi) { num = 0.05f; } thatEyeEulerAngle = thatEyeEulerAngle * (1f - num) + eulerAngles2 * num; } else { thatEyeEulerAngle = thatEyeEulerAngle * 0.95f; } that.trsEyeL.localRotation = that.quaDefEyeL * Quaternion.Euler(0.0f, thatEyeEulerAngle.x * -0.2f, thatEyeEulerAngle.z * -0.1f); that.trsEyeR.localRotation = that.quaDefEyeR * Quaternion.Euler(0.0f, thatEyeEulerAngle.x * 0.2f, thatEyeEulerAngle.z * 0.1f); }
Vector3 updateEyeTargetPos(TBody tbody) { TBody that = tbody; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTargetWorldPos:ワールド座標系での視線のターゲット位置 Vector3 eyeTargetWorldPos; if (that.trsLookTarget == null) { eyeTargetWorldPos = that.trsHead.TransformPoint(that.offsetLookTarget); if (that.boEyeSorashi) { // num : 顔の前方と顔→カメラベクトルの内積。1.0に近ければ、カメラが顔の正面にある float num = Vector3.Dot( (eyeTargetWorldPos - that.trsHead.position).normalized, (mainCamera.transform.position - that.trsHead.position).normalized); if (that.EyeSorashiCnt > 0) { ++that.EyeSorashiCnt; if (that.EyeSorashiCnt > 200) { that.EyeSorashiCnt = 0; } } // カメラが顔の前方にあり、なおかつ前回の変更から 200 フレーム経過しているなら、新しい「前方」を決める if (num > 0.9f && that.EyeSorashiCnt == 0) { that.offsetLookTarget = !that.EyeSorashiTgl ? new Vector3(-0.6f, 1f, 0.6f) : new Vector3(-0.5f, 1f, -0.7f); that.EyeSorashiTgl = !that.EyeSorashiTgl; that.EyeSorashiCnt = 1; } } } else { eyeTargetWorldPos = that.trsLookTarget.position; } return eyeTargetWorldPos; }
public SlotInfo(TBody.SlotID id, MPN mpn, string displayName, bool enable) :this(id, mpn, displayName, enable, true) { }
void Update() { if (Application.loadedLevel != 5) { return; } if (editViewReset == null) { editViewReset = UnityEngine.Object.FindObjectOfType <EditViewReset>(); } if (sceneEdit == null) { sceneEdit = UnityEngine.Object.FindObjectOfType <SceneEdit>(); } { string gridName = "/UI Root/PresetButtonPanel/ItemPresetsViewer/Scroll View/Grid"; GameObject goGrid = GameObject.Find(gridName); if (goGrid != null) { if (poseButtonCallback == null) { poseButtonCallback = new EventDelegate.Callback(ClickPoseCallback); } foreach (Transform t in goGrid.transform) { if (!t.name.StartsWith("Pose_")) { continue; } GameObject go = t.gameObject; UIButton uiButton = go.GetComponent <UIButton>(); EventDelegate.Add(uiButton.onClick, poseButtonCallback); } } } if (editViewReset != null && sceneEdit != null) { Maid maid = GameMain.Instance.CharacterMgr.GetMaid(0); if (bLevelWasLoaded) { bLevelWasLoaded = false; LoadSettings(maid); } // UICamera.InputEnable が False になるとサムネール撮影用のために着衣状態になる TBody tbody = maid == null ? null : maid.body0; if (tbody != null && fieldInfo_TBody_m_eMaskMode != null && UICamera.InputEnable) { lastMaid = maid; bLastAutoCam = editViewReset.GetVisibleAutoCam(); bLastEyeToCam = editViewReset.GetVisibleEyeToCam(); lastBgName = GameMain.Instance.BgMgr.GetBGName(); lastClothMaskMode = (TBody.MaskMode)fieldInfo_TBody_m_eMaskMode.GetValue(tbody); lastCameraPos = mainCamera.GetPos(); lastCameraTargetPos = mainCamera.GetTargetPos(); lastCameraDistance = mainCamera.GetDistance(); lastCameraRotation = Camera.main.gameObject.transform.rotation; lastCameraFov = Camera.main.fieldOfView; } } }
public void SetValue(TBody body) { Issi = Convert.ToInt32(body.GetIssi()); Identitier = Convert.ToByte(36); Len = Convert.ToInt16(96); }
void newMoveHead(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTarget_world) { TBody that = tbody; Maid maid = tbody.maid; float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.speed", 0.05f); float paramLateral = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.lateral", 60.0f); float paramAbove = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.above", 40.0f); float paramBelow = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.below", 20.0f); float paramBehind = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.behind", 170.0f); float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsx", 0.0f); float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsy", 0.0f); float paramOfsZ = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsz", 0.0f); // 正面の角度 float frontangle = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.frontangle", 0f); Quaternion frontquaternion = Quaternion.Euler(0f, 0f, frontangle); // モーションにしたがっている場合 (HeadToCamPer=0f) はオフセットをつけない paramOfsX *= that.HeadToCamPer; paramOfsY *= that.HeadToCamPer; paramOfsZ *= that.HeadToCamPer; Vector3 basePosition = that.trsHead.position; Quaternion baseRotation = that.trsNeck.rotation * frontquaternion; Vector3 target_local = Quaternion.Inverse(baseRotation) * (eyeTarget_world - basePosition); //追従割合 Quaternion local_angle = Quaternion.FromToRotation(Vector3.up, target_local); Vector3 local_auler = local_angle.eulerAngles; float headrateup = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headrateup", 1f); float headratedown = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headratedown", 1f); float headratehorizon = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headratehorizon", 1f); float dx = 0; float dy = 0; if (local_auler.x < 180f) { dx = local_auler.x * (headratehorizon - 1f); } else { dx = (local_auler.x - 360f) * (headratehorizon - 1f); } if (local_auler.z < 180f) { dy = local_auler.z * (headrateup - 1f); } else { dy = (local_auler.z - 360f) * (headratedown - 1f); } target_local = Quaternion.Euler(dx, 0f, dy) * target_local; target_local = Quaternion.Euler(paramOfsX, 0f, paramOfsY) * target_local; Vector3 target_world = (baseRotation * target_local) + basePosition; // 顔が向くべき方向を算出 Quaternion newHeadRotation_world = CalcNewHeadRotation( paramLateral, paramAbove, paramBelow, paramBehind, baseRotation, basePosition, target_world, eyeTarget_world); newHeadRotation_world = newHeadRotation_world * Quaternion.Euler(0f, paramOfsZ, 0f); // TBody.HeadToCamPer を「正面向き度合い」として加味する newHeadRotation_world = Quaternion.Slerp(that.trsHead.rotation, newHeadRotation_world, that.HeadToCamPer); // 角度 float inclinerate = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.inclinerate", 0f); Quaternion newHeadRotation_Local = Quaternion.Inverse(baseRotation) * newHeadRotation_world; Vector3 newHeadRotationEulerLocal = newHeadRotation_Local.eulerAngles; if (newHeadRotationEulerLocal.x > 180f) { newHeadRotationEulerLocal = new Vector3( newHeadRotationEulerLocal.x - 360f, newHeadRotationEulerLocal.y, newHeadRotationEulerLocal.z); } newHeadRotationEulerLocal = new Vector3( newHeadRotationEulerLocal.x, newHeadRotationEulerLocal.y + (newHeadRotationEulerLocal.x * inclinerate), newHeadRotationEulerLocal.z); newHeadRotation_Local = Quaternion.Euler(newHeadRotationEulerLocal); newHeadRotation_world = baseRotation * newHeadRotation_Local; float s = paramSpeed; // 前回の回転よりも差が大きすぎる場合はリセットする if (externalValues.bReset) { externalValues.bReset = false; externalValues.prevQuat = that.trsHead.rotation; s = 0f; } // モーションにしたがっている場合 (HeadToCamPer=0f) は補間しない s = Mathf.Lerp(1f, s, that.HeadToCamPer); // 実際の回転 that.trsHead.rotation = Quaternion.Slerp(externalValues.prevQuat, newHeadRotation_world, s); }
// 目を常時カメラに向ける void EyeToCam(Maid maid, TBody tbody) { float fEyeToCam = ExSaveData.GetFloat(maid, PluginName, "EYETOCAM", 0f); if (fEyeToCam < -0.5f) { tbody.boEyeToCam = false; } else if (fEyeToCam > 0.5f) { tbody.boEyeToCam = true; } }
// 元の MoveHeadAndEye 相当の処理 void originalTbodyMoveHeadAndEyeCallback2(TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle) { TBody that = tbody; CameraMain mainCamera = GameMain.Instance.MainCamera; // eyeTargetWorldPos:ワールド座標系での視線のターゲット位置 Vector3 eyeTargetWorldPos = updateEyeTargetPos(tbody); // COM3D2の追加処理 if (tbody.boLockHeadAndEye) { return; } // HeadToCamPer:最終的に顔がカメラを向く度合い // 0 なら元の頭の向き、1 ならカメラの向き if (that.boHeadToCam) { that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed; } else { that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed; } that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer); that.boChkEye = false; originalMoveHead(tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTargetWorldPos); if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null) { return; } // 目の追従処理 if (that.boEyeToCam && that.boChkEye) { Vector3 toDirection2 = Quaternion.Inverse(that.trsHead.rotation) * (eyeTargetWorldPos - that.trsHead.position); Quaternion quaternion2 = new Quaternion(); quaternion2.SetFromToRotation(Vector3.up, toDirection2); Vector3 eulerAngles2 = PluginHelper.NormalizeEulerAngles(quaternion2.eulerAngles); Vector3 view = Vector3.Normalize(eyeTargetWorldPos - that.trsEyeL.position); quaternion2.SetLookRotation(view, Vector3.up); Quaternion quaternion3 = quaternion2 * Quaternion.Euler(0.0f, 90f, 0.0f); float num = 0.5f; if (that.boEyeSorashi) { num = 0.05f; } thatEyeEulerAngle = thatEyeEulerAngle * (1f - num) + eulerAngles2 * num; } else { thatEyeEulerAngle = thatEyeEulerAngle * 0.95f; } that.trsEyeL.localRotation = that.quaDefEyeL * Quaternion.Euler(0.0f, thatEyeEulerAngle.x * -0.2f, thatEyeEulerAngle.z * -0.1f); that.trsEyeR.localRotation = that.quaDefEyeR * Quaternion.Euler(0.0f, thatEyeEulerAngle.x * 0.2f, thatEyeEulerAngle.z * 0.1f); }
// 瞳の角度を目の角度に合わせて補正 void RotatePupil(Maid maid, TBody tbody) { /* // 注意:TBody.MoveHeadAndEye内で trsEye[L,R].localRotation が上書きされているため、 // この値は TBody.MoveHeadAndEyeが呼ばれるたびに書き換える必要がある float eyeAng = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f); Vector3 eea = (Vector3)Helper.GetInstanceField(typeof(TBody), tbody, "EyeEulerAngle"); tbody.trsEyeL.localRotation = tbody.quaDefEyeL * Quaternion.Euler(eyeAng, eea.x * -0.2f, eea.z * -0.1f); tbody.trsEyeR.localRotation = tbody.quaDefEyeR * Quaternion.Euler(-eyeAng, eea.x * 0.2f, eea.z * 0.1f); */ }
public override bool IKUpdate(TBody body) { body.IKCtrl.IKUpdate(); return(true); }
/// <summary> /// TBody.MoveHeadAndEye の処理終了後に呼ばれるコールバック /// 表示されている間は毎フレーム呼び出される /// </summary> void tbodyMoveHeadAndEyeCallback(TBody tbody) { tbodyMoveHeadAndEye.Callback(tbody); if (tbody.boMAN || tbody.trsEyeL == null || tbody.trsEyeR == null) { return; } Maid maid = PluginHelper.GetMaid(tbody); if (maid == null) { return; } if (maid.Visible) { DisableLipSync(maid); DisableFaceAnime(maid); Mabataki(maid); EyeToCam(maid, tbody); HeadToCam(maid, tbody); RotatePupil(maid, tbody); SetLipSyncIntensity(maid, tbody); ForeArmFix(maid); } }
public override object GetIkCtrlPoint(TBody body, string hand = "右手") { var obj = body.IKCtrl.GetIKData(hand); return(obj); }
void newMoveHead(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTarget_world) { TBody that = tbody; Maid maid = tbody.maid; float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.speed", 0.05f); float paramLateral = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.lateral", 60.0f); float paramAbove = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.above", 40.0f); float paramBelow = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.below", 20.0f); float paramBehind = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.behind", 170.0f); float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsx", 0.0f); float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsy", 0.0f); float paramOfsZ = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsz", 0.0f); // モーションにしたがっている場合 (HeadToCamPer=0f) はオフセットをつけない paramOfsX *= that.HeadToCamPer; paramOfsY *= that.HeadToCamPer; paramOfsZ *= that.HeadToCamPer; Vector3 basePosition = that.trsNeck.position; Quaternion baseRotation = that.trsNeck.rotation; Vector3 target_local = Quaternion.Inverse(baseRotation) * (eyeTarget_world - basePosition); target_local = Quaternion.Euler(paramOfsX, 0f, paramOfsY) * target_local; Vector3 target_world = (baseRotation * target_local) + basePosition; // 顔が向くべき方向を算出 Quaternion newHeadRotation_world = CalcNewHeadRotation( paramLateral, paramAbove, paramBelow, paramBehind, baseRotation, basePosition, target_world); newHeadRotation_world = newHeadRotation_world * Quaternion.Euler(0f, paramOfsZ, 0f); // TBody.HeadToCamPer を「正面向き度合い」として加味する newHeadRotation_world = Quaternion.Slerp(that.trsHead.rotation, newHeadRotation_world, that.HeadToCamPer); float s = paramSpeed; // 前回の回転よりも差が大きすぎる場合はリセットする if (externalValues.bReset) { externalValues.bReset = false; externalValues.prevQuat = that.trsHead.rotation; s = 0f; } // モーションにしたがっている場合 (HeadToCamPer=0f) は補間しない s = Mathf.Lerp(1f, s, that.HeadToCamPer); // 実際の回転 that.trsHead.rotation = Quaternion.Slerp(externalValues.prevQuat, newHeadRotation_world, s); }
// スライダー範囲を拡大 void WideSlider(Maid maid) { if (!ExSaveData.GetBool(maid, PluginName, "WIDESLIDER", false)) { return; } TBody tbody = maid.body0; string[] PropNames = BoneMorph_PropNames; if (tbody == null || tbody.bonemorph == null || tbody.bonemorph.bones == null || PropNames == null) { return; } BoneMorph_ boneMorph_ = tbody.bonemorph; // スケール変更するボーンのリスト Dictionary <string, Vector3> boneScale = new Dictionary <string, Vector3>(); // ポジション変更するボーンのリスト Dictionary <string, Vector3> bonePosition = new Dictionary <string, Vector3>(); //この配列に記載があるボーンは頭に影響を与えずにTransformを反映させる。 //ただしボディに繋がっている中のアレは影響を受ける。 string[] ignoreHeadBones = new string[] { "Bip01 Spine1a" }; float eyeAngAngle; float eyeAngX; float eyeAngY; { float ra = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f); float rx = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.x", 0f); float ry = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.y", 0f); rx += -9f; ry += -17f; rx /= 1000f; ry /= 1000f; eyeAngAngle = ra; eyeAngX = rx; eyeAngY = ry; } Vector3 thiScl = new Vector3( 1.0f, ExSaveData.GetFloat(maid, PluginName, "THISCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "THISCL.width", 1f)); Vector3 thiPosL; Vector3 thiPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "THIPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "THIPOS.z", 0f); float dy = 0.0f; thiPosL = new Vector3(dy, dz / 1000f, -dx / 1000f); thiPosR = new Vector3(dy, dz / 1000f, dx / 1000f); } bonePosition["Hip_L"] = thiPosL; bonePosition["Bip01 L Thigh"] = thiPosL; bonePosition["Hip_R"] = thiPosR; bonePosition["Bip01 R Thigh"] = thiPosR; Vector3 skirtPos; { float dx = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.x", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.y", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "SKTPOS.z", 0f); skirtPos = new Vector3(-dz / 10f, -dy / 10f, dx / 10f); } bonePosition["Skirt"] = skirtPos; Vector3 muneSubPosL; Vector3 muneSubPosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MUNESUBPOS.y", 0f); muneSubPosL = new Vector3(-dy / 10f, dz / 10f, -dx / 10f); muneSubPosR = new Vector3(-dy / 10f, -dz / 10f, -dx / 10f); } bonePosition["Mune_L_sub"] = muneSubPosL; bonePosition["Mune_R_sub"] = muneSubPosR; Vector3 munePosL; Vector3 munePosR; { float dx = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.x", 0f); float dz = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.z", 0f); float dy = ExSaveData.GetFloat(maid, PluginName, "MUNEPOS.y", 0f); munePosL = new Vector3(dz / 10f, -dy / 10f, dx / 10f); munePosR = new Vector3(dz / 10f, -dy / 10f, -dx / 10f); } bonePosition["Mune_L"] = munePosL; bonePosition["Mune_R"] = munePosR; // スケール変更するボーンをリストに一括登録 SetBoneScaleFromList(boneScale, maid, boneAndPropNameList); Transform tEyePosL = null; Transform tEyePosR = null; float sliderScale = 20f; for (int i = boneMorph_.bones.Count - 1; i >= 0; i--) { BoneMorphLocal boneMorphLocal = boneMorph_.bones[i]; Vector3 scl = new Vector3(1f, 1f, 1f); Vector3 pos = boneMorphLocal.pos; for (int j = 0; j < (int)PropNames.Length; j++) { float s = 1f; switch (j) { case 0: s = boneMorph_.SCALE_Kubi; break; case 1: s = boneMorph_.SCALE_Ude; break; case 2: s = boneMorph_.SCALE_EyeX; break; case 3: s = boneMorph_.SCALE_EyeY; break; case 4: s = boneMorph_.Postion_EyeX * (0.5f + boneMorph_.Postion_EyeY * 0.5f); break; case 5: s = boneMorph_.Postion_EyeY; break; case 6: s = boneMorph_.SCALE_HeadX; break; case 7: s = boneMorph_.SCALE_HeadY; break; case 8: s = boneMorph_.SCALE_DouPer; if (boneMorphLocal.Kahanshin == 0f) { s = 1f - s; } break; case 9: s = boneMorph_.SCALE_Sintyou; break; case 10: s = boneMorph_.SCALE_Koshi; break; case 11: s = boneMorph_.SCALE_Kata; break; case 12: s = boneMorph_.SCALE_West; break; default: s = 1f; break; } if ((boneMorphLocal.atr & 1 << (j & 31)) != 0) { Vector3 v0 = boneMorphLocal.vecs_min[j]; Vector3 v1 = boneMorphLocal.vecs_max[j]; Vector3 n0 = v0 * sliderScale - v1 * (sliderScale - 1f); Vector3 n1 = v1 * sliderScale - v0 * (sliderScale - 1f); float f = (s + sliderScale - 1f) * (1f / (sliderScale * 2.0f - 1f)); scl = Vector3.Scale(scl, Vector3.Lerp(n0, n1, f)); } if ((boneMorphLocal.atr & 1 << (j + 16 & 31)) != 0) { Vector3 v0 = boneMorphLocal.vecs_min[j + 16]; Vector3 v1 = boneMorphLocal.vecs_max[j + 16]; Vector3 n0 = v0 * sliderScale - v1 * (sliderScale - 1f); Vector3 n1 = v1 * sliderScale - v0 * (sliderScale - 1f); float f = (s + sliderScale - 1f) * (1f / (sliderScale * 2.0f - 1f)); pos = Vector3.Scale(pos, Vector3.Lerp(n0, n1, f)); } } Transform linkT = boneMorphLocal.linkT; if (linkT == null) { continue; } string name = linkT.name; if (name != null && name.Contains("Thigh_SCL_")) { boneMorph_.SnityouOutScale = Mathf.Pow(scl.x, 0.9f); } // リストに登録されているボーンのスケール設定 if (name != null && boneScale.ContainsKey(name)) { scl = Vector3.Scale(scl, boneScale[name]); } // リストに登録されているボーンのポジション設定 if (name != null && bonePosition.ContainsKey(name)) { pos += bonePosition[name]; } // ignoreHeadBonesに登録されている場合はヒラエルキーを辿って頭のツリーを無視 if (name != null && !(ignoreHeadBones.Contains(name) && getHiraerchy(linkT).Contains("_BO_body001/Bip01"))) { linkT.localScale = scl; linkT.localPosition = pos; } if (name != null) { if (name == "Eyepos_L") { tEyePosL = linkT; } else if (name == "Eyepos_R") { tEyePosR = linkT; } } } // 目のサイズ・角度変更 // EyeScaleRotate : 目のサイズと角度変更する CM3D.MaidVoicePich.Plugin.cs の追加メソッド // http://pastebin.com/DBuN5Sws // その1>>923 // http://jbbs.shitaraba.net/bbs/read.cgi/game/55179/1438196715/923 if (tEyePosL != null) { Transform linkT = tEyePosL; Vector3 localCenter = linkT.localPosition + (new Vector3(0f, eyeAngY, eyeAngX)); // ローカル座標系での回転中心位置 Vector3 worldCenter = linkT.parent.TransformPoint(localCenter); // ワールド座標系での回転中心位置 Vector3 localAxis = new Vector3(-1f, 0f, 0f); // ローカル座標系での回転軸 Vector3 worldAxis = linkT.TransformDirection(localAxis); // ワールド座標系での回転軸 linkT.localRotation = new Quaternion(-0.00560432f, -0.001345155f, 0.06805823f, 0.9976647f); // 初期の回転量 linkT.RotateAround(worldCenter, worldAxis, eyeAngAngle); } if (tEyePosR != null) { Transform linkT = tEyePosR; Vector3 localCenter = linkT.localPosition + (new Vector3(0f, eyeAngY, -eyeAngX)); // ローカル座標系での回転中心位置 Vector3 worldCenter = linkT.parent.TransformPoint(localCenter); // ワールド座標系での回転中心位置 Vector3 localAxis = new Vector3(-1f, 0f, 0f); // ローカル座標系での回転軸 Vector3 worldAxis = linkT.TransformDirection(localAxis); // ワールド座標系での回転軸 linkT.localRotation = new Quaternion(0.9976647f, 0.06805764f, -0.001350592f, -0.005603582f); // 初期の回転量 linkT.RotateAround(worldCenter, worldAxis, -eyeAngAngle); } }