void jiggleBonePostLateUpdateSelef(jiggleBone jiggleBone) { // 変更処理が実行されなければ終了 if (jiggleBone.transform.localScale == jiggleBoneScaleBackUp) { return; } // jiggleBoneからMaidを取得 Maid maid = null; Transform t = jiggleBone.transform; while (maid == null && t != null) { maid = t.GetComponent <Maid>(); t = t.parent; } if (maid == null) { return; } // スライダー拡張オフなら何もしない if (!ExSaveData.GetBool(maid, PluginName, "WIDESLIDER", false)) { return; } float sx = ExSaveData.GetFloat(maid, PluginName, "MUNESCL.height", 1f); float sy = ExSaveData.GetFloat(maid, PluginName, "MUNESCL.depth", 1f); float sz = ExSaveData.GetFloat(maid, PluginName, "MUNESCL.width", 1f); Vector3 scl = jiggleBone.transform.localScale; jiggleBone.transform.localScale = new Vector3(scl.x * sx, scl.y * sy, scl.z * sz); }
void SetBoneScale(Dictionary <string, Vector3> dictionary, string boneName, Maid maid, string propName) { dictionary[boneName] = new Vector3( ExSaveData.GetFloat(maid, PluginName, propName + ".height", 1f), ExSaveData.GetFloat(maid, PluginName, propName + ".depth", 1f), ExSaveData.GetFloat(maid, PluginName, propName + ".width", 1f)); }
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 EyeBall(Maid maid) { TBody tbody = maid.body0; if (tbody != null && tbody.trsEyeL != null && tbody.trsEyeR != null) { float w = ExSaveData.GetFloat(maid, PluginName, "EYEBALL.width", 1f); float h = ExSaveData.GetFloat(maid, PluginName, "EYEBALL.height", 1f); tbody.trsEyeL.localScale = new Vector3(1f, h, w); tbody.trsEyeR.localScale = new Vector3(1f, h, w); } }
/// <summary> /// AudioSourceMgr.Play および AudioSourceMgr.PlayOneShot の処理終了後に呼ばれるコールバック。 /// ピッチ変更を行う /// </summary> static void SetAudioPitch(AudioSourceMgr audioSourceMgr) { Maid maid = PluginHelper.GetMaid(audioSourceMgr); if (maid == null || audioSourceMgr.audiosource == null || !audioSourceMgr.audiosource.isPlaying) { return; } float f = ExSaveData.GetFloat(maid, PluginName, "PITCH", 0f); audioSourceMgr.audiosource.pitch = 1f + f; }
// 顔を常時カメラに向ける 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; } }
// 目を常時カメラに向ける 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; } }
void LoadCameraSettings(Maid maid) { if (maid == null || !maid.Visible) { return; } bool autoCam = ExSaveData.GetBool(maid, PluginName, "AutoCameraInitialValue", true); if (autoCam) { return; } float cameraPosX = ExSaveData.GetFloat(maid, PluginName, "CameraPos.x", float.NaN); float cameraPosY = ExSaveData.GetFloat(maid, PluginName, "CameraPos.y", float.NaN); float cameraPosZ = ExSaveData.GetFloat(maid, PluginName, "CameraPos.z", float.NaN); float cameraTargetPosX = ExSaveData.GetFloat(maid, PluginName, "CameraTargetPos.x", float.NaN); float cameraTargetPosY = ExSaveData.GetFloat(maid, PluginName, "CameraTargetPos.y", float.NaN); float cameraTargetPosZ = ExSaveData.GetFloat(maid, PluginName, "CameraTargetPos.z", float.NaN); float cameraDistance = ExSaveData.GetFloat(maid, PluginName, "CameraDistance", float.NaN); float cameraRotatationX = ExSaveData.GetFloat(maid, PluginName, "CameraRotation.x", float.NaN); float cameraRotatationY = ExSaveData.GetFloat(maid, PluginName, "CameraRotation.y", float.NaN); float cameraRotatationZ = ExSaveData.GetFloat(maid, PluginName, "CameraRotation.z", float.NaN); float cameraRotatationW = ExSaveData.GetFloat(maid, PluginName, "CameraRotation.w", float.NaN); float cameraFov = ExSaveData.GetFloat(maid, PluginName, "CameraFov", float.NaN); if (!float.IsNaN(cameraRotatationX) && !float.IsNaN(cameraRotatationY) && !float.IsNaN(cameraRotatationZ) && !float.IsNaN(cameraRotatationW)) { Camera.main.gameObject.transform.rotation = new Quaternion(cameraRotatationX, cameraRotatationY, cameraRotatationZ, cameraRotatationW); } if (!float.IsNaN(cameraPosX) && !float.IsNaN(cameraPosY) && !float.IsNaN(cameraPosZ)) { mainCamera.SetPos(new Vector3(cameraPosX, cameraPosY, cameraPosZ)); } if (!float.IsNaN(cameraTargetPosX) && !float.IsNaN(cameraTargetPosY) && !float.IsNaN(cameraTargetPosZ)) { mainCamera.SetTargetPos(new Vector3(cameraTargetPosX, cameraTargetPosY, cameraTargetPosZ), true); } if (!float.IsNaN(cameraDistance)) { mainCamera.SetDistance(cameraDistance, true); } if (!float.IsNaN(cameraFov)) { Camera.main.fieldOfView = cameraFov; } }
// リップシンク強度指定 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 Mabataki(Maid maid) { float mabatakiVal = (float)Helper.GetInstanceField(typeof(Maid), maid, "MabatakiVal"); float f = Mathf.Clamp01(1f - ExSaveData.GetFloat(maid, PluginName, "MABATAKI", 1f)); float mMin = Mathf.Asin(f); float mMax = (float)Math.PI - mMin; mMin = Mathf.Pow(mMin / (float)Math.PI, 0.5f); mMax = Mathf.Pow(mMax / (float)Math.PI, 0.5f); mabatakiVal = Mathf.Clamp(mabatakiVal, mMin, mMax); if (ExSaveData.GetBool(maid, PluginName, "MUHYOU", false)) { // 無表情の場合、常に目を固定 mabatakiVal = mMin; } Helper.SetInstanceField(typeof(Maid), maid, "MabatakiVal", mabatakiVal); }
// 新しい 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 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 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); } }