// ForeArmFix : 前腕の歪みを修正する CM3D.MaidVoicePitch.Plugin.cs の追加メソッド // CM3D.MaidVoicePitch.Plugin を適用しメイドのフリーコメント欄に #FARMFIX# の記述で前腕の歪みを修正する。 // 前腕歪みバグを修正 void ForeArmFix(Maid maid) { if (!ExSaveData.GetBool(maid, PluginName, "FARMFIX", false)) { return; } BoneMorph_ bm_ = maid.body0.bonemorph; List <Transform> tListFAL = new List <Transform>(); List <Transform> tListFAR = new List <Transform>(); float sclUAx = -1f; for (int i = 0; i < bm_.bones.Count; i++) { if (bm_.bones[i].linkT == null) { continue; } if (bm_.bones[i].linkT.name == "Bip01 L Forearm") { tListFAL.Add(bm_.bones[i].linkT); } if (bm_.bones[i].linkT.name == "Bip01 R Forearm") { tListFAR.Add(bm_.bones[i].linkT); } if (sclUAx < 0f && bm_.bones[i].linkT.name == "Bip01 L UpperArm") { sclUAx = bm_.bones[i].linkT.localScale.x; } } if (sclUAx < 0f || tListFAL.Count < 1 || tListFAR.Count < 1) { return; } Vector3 sclUA = new Vector3(sclUAx, 1f, 1f); Vector3 antisclUA_d = new Vector3(1f / sclUAx - 1f, 0f, 0f); Vector3 eaFAL = tListFAL[0].localRotation.eulerAngles; Vector3 eaFAR = tListFAR[0].localRotation.eulerAngles; Quaternion antirotFAL = Quaternion.Euler(eaFAL - new Vector3(180f, 180f, 180f)); Quaternion antirotFAR = Quaternion.Euler(eaFAR - new Vector3(180f, 180f, 180f)); Vector3 sclFAL_d = antirotFAL * antisclUA_d; Vector3 sclFAR_d = antirotFAR * antisclUA_d; Vector3 antisclFAL = new Vector3(1f, 1f, 1f) + new Vector3(Mathf.Abs(sclFAL_d.x), Mathf.Abs(sclFAL_d.y), Mathf.Abs(sclFAL_d.z)); Vector3 antisclFAR = new Vector3(1f, 1f, 1f) + new Vector3(Mathf.Abs(sclFAR_d.x), Mathf.Abs(sclFAR_d.y), Mathf.Abs(sclFAR_d.z)); foreach (Transform t in tListFAL) { t.localScale = Vector3.Scale(antisclFAL, sclUA); } foreach (Transform t in tListFAR) { t.localScale = Vector3.Scale(antisclFAR, sclUA); } }
/// <summary> /// BoneMorph_.Blend の処理終了後に呼ばれるコールバック。 /// 初期化、設定変更時のみ呼び出される。 /// ボーンのブレンド処理が行われる際、拡張スライダーに関連する補正は基本的にここで行う。 /// 毎フレーム呼び出されるわけではないことに注意 /// </summary> void boneMorph_BlendCallback(BoneMorph_ boneMorph_) { Maid maid = PluginHelper.GetMaid(boneMorph_); if (maid == null) { return; } WideSlider(maid); EyeBall(maid); }
/// <summary> /// BoneMorph_.Blend の処理終了後に呼ばれるコールバック。 /// 初期化、設定変更時のみ呼び出される。 /// ボーンのブレンド処理が行われる際、拡張スライダーに関連する補正は基本的にここで行う。 /// 毎フレーム呼び出されるわけではないことに注意 /// </summary> void boneMorph_BlendCallback(BoneMorph_ boneMorph_) { Maid maid = PluginHelper.GetMaid(boneMorph_); if (maid == null) { return; } WideSlider(maid); //EyeBall(maid); if (maid.body0 != null && maid.body0.isLoadedBody) { IKPreInit(maid); maid.body0.fullBodyIK.Init(); } }
// BoneMorph_を手がかりに、Maidを得る public static Maid GetMaid(BoneMorph_ boneMorph_) { if (boneMorph_ == null) { return(null); } CharacterMgr cm = GameMain.Instance.CharacterMgr; for (int i = 0, n = cm.GetStockMaidCount(); i < n; i++) { Maid maid = cm.GetStockMaid(i); if (maid.body0 == null || maid.body0.bonemorph == null) { continue; } if (object.ReferenceEquals(maid.body0.bonemorph, boneMorph_)) { return(maid); } } return(null); }
// スライダー範囲を拡大 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); } } }
// スライダー範囲を拡大 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); } }
// スライダー範囲を拡大 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; 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); } // 骨盤 Vector3 pelvisScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "PELSCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "PELSCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "PELSCL.width", 1f)); // スカート Vector3 sktScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "SKTSCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "SKTSCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "SKTSCL.width", 1f)); // 胴(下腹部周辺) Vector3 spineScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "SPISCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "SPISCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "SPISCL.width", 1f)); // 胴0a(腹部周辺) Vector3 spine0aScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "S0ASCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "S0ASCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "S0ASCL.width", 1f)); // 胴1_(みぞおち周辺) Vector3 spine1Scl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "S1_SCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "S1_SCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "S1_SCL.width", 1f)); // 胴1a(首・肋骨周辺) Vector3 spine1aScl = new Vector3( ExSaveData.GetFloat(maid, PluginName, "S1ASCL.height", 1f), ExSaveData.GetFloat(maid, PluginName, "S1ASCL.depth", 1f), ExSaveData.GetFloat(maid, PluginName, "S1ASCL.width", 1f)); 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) { // 何もしない } else if (name == "Eyepos_L") { // 何もしない } else if (name == "Eyepos_R") { // 何もしない } else if (name == "Hip_L") { scl = Vector3.Scale(scl, pelvisScl); pos += thiPosL; } else if (name == "Hip_R") { scl = Vector3.Scale(scl, pelvisScl); pos += thiPosR; } else if (name == "Skirt") { scl = Vector3.Scale(scl, sktScl); } else if (name == "Bip01 L Thigh") { scl = Vector3.Scale(scl, thiScl); pos += thiPosL; } else if (name == "Bip01 R Thigh") { scl = Vector3.Scale(scl, thiScl); pos += thiPosR; } else if (name == "Bip01 Pelvis_SCL_") { scl = Vector3.Scale(scl, pelvisScl); } else if (name == "Bip01 Spine_SCL_") { scl = Vector3.Scale(scl, spineScl); } else if (name == "Bip01 Spine0a_SCL_") { scl = Vector3.Scale(scl, spine0aScl); } else if (name == "Bip01 Spine1_SCL_") { scl = Vector3.Scale(scl, spine1Scl); } else if (name == "Bip01 Spine1a_SCL_") { scl = Vector3.Scale(scl, spine1aScl); } linkT.localPosition = pos; linkT.localScale = scl; 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); } }