// 目と口の表情変化をやめる void DisableFaceAnime(Maid maid) { bool bMuhyou = ExSaveData.GetBool(maid, PluginName, "MUHYOU", false); bool bHyoujouOff = ExSaveData.GetBool(maid, PluginName, "HYOUJOU_OFF", false); if (bHyoujouOff || bMuhyou) { maid.FaceAnime("", 0f, 0); } }
// リップシンク(口パク)抑制 void DisableLipSync(Maid maid) { bool bMuhyou = ExSaveData.GetBool(maid, PluginName, "MUHYOU", false); bool bLipSyncOff = ExSaveData.GetBool(maid, PluginName, "LIPSYNC_OFF", false); if (bLipSyncOff || bMuhyou) { Helper.SetInstanceField(typeof(Maid), maid, "m_bFoceKuchipakuSelfUpdateTime", true); } }
/// <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 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); } }
// 目を常時カメラに向ける 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 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 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; } }
static void Update(Maid maid, string PluginName) { if (!maid.Visible) { return; } string fname = ExSaveData.Get(maid, PluginName, "SLIDER_TEMPLATE", null); SliderTemplate sliderTemplate = sliderTemplates.Get(fname); if (sliderTemplate != null && !sliderTemplate.IsLoaded) { sliderTemplate.WriteProps(maid); sliderTemplate.IsLoaded = true; } }
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); } }
static void Update(Maid maid, string PluginName) { if (!maid.Visible) { return; } string fname = ExSaveData.Get(maid, PluginName, "SLIDER_TEMPLATE", "UnityInjector/Config/MaidVoicePitchSlider.xml"); SliderTemplate sliderTemplate = sliderTemplates.Get(fname); string guid = maid.Param.status.guid; if (sliderTemplate != null && !sliderTemplate.LoadedMaidGuids.Contains(guid)) { sliderTemplate.WriteProps(maid); sliderTemplate.LoadedMaidGuids.Add(guid); } }
static bool TagPropSet(BaseKagManager baseKagManager, KagTagSupport tag_data) { Maid maidAndMan = GetMaidAndMan(tag_data); if (maidAndMan != null && ExSaveData.GetBool(maidAndMan, PluginName, "PROPSET_OFF", false)) { string str = tag_data.GetTagProperty("category").AsString(); if (Array.IndexOf(PluginHelper.MpnStrings, str) >= 0) { // Helper.Log("PROPSET_OFF(category={0}) -> match", str); return(false); } } return(baseKagManager.TagPropSet(tag_data)); }
// リップシンク強度指定 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); }
// 動作していない古い設定を削除する static void CleanupExSave() { string[] obsoleteSettings = { "WIDESLIDER.enable", "PROPSET_OFF.enable", "LIPSYNC_OFF.enable", "HYOUJOU_OFF.enable", "EYETOCAMERA_OFF.enable", "MUHYOU.enable", "FARMFIX.enable", "EYEBALL.enable", "EYE_ANG.enable", "PELSCL.enable", "SKTSCL.enable", "THISCL.enable", "THIPOS.enable", "PELVIS.enable", "FARMFIX.enable", "SPISCL.enable", "S0ASCL.enable", "S1_SCL.enable", "S1ASCL.enable", "FACE_OFF.enable", "FACEBLEND_OFF.enable", // 以下0.2.4で廃止 "FACE_ANIME_SPEED", "MABATAKI_SPEED", "PELVIS", "PELVIS.x", "PELVIS.y", "PELVIS.z", }; CharacterMgr cm = GameMain.Instance.CharacterMgr; for (int i = 0, n = cm.GetStockMaidCount(); i < n; i++) { Maid maid = cm.GetStockMaid(i); foreach (string s in obsoleteSettings) { ExSaveData.Remove(maid, PluginName, s); } { string fname = ExSaveData.Get(maid, PluginName, "SLIDER_TEMPLATE", null); if (string.IsNullOrEmpty(fname)) { ExSaveData.Set(maid, PluginName, "SLIDER_TEMPLATE", "UnityInjector/Config/MaidVoicePitchSlider.xml", true); } } } string[] obsoleteGlobalSettings = { "TEST_GLOBAL_KEY" }; foreach (string s in obsoleteGlobalSettings) { ExSaveData.GlobalRemove(PluginName, s); } }
static bool TagFace(BaseKagManager baseKagManager, KagTagSupport tag_data) { Maid maidAndMan = GetMaidAndMan(tag_data); if (maidAndMan == null) { return(false); } if (maidAndMan != null && ExSaveData.GetBool(maidAndMan, PluginName, "FACE_OFF", false)) { // Helper.Log("FACE_OFF() -> match"); return(false); } baseKagManager.CheckAbsolutelyNecessaryTag(tag_data, "face", new string[] { "name" }); string oldName = tag_data.GetTagProperty("name").AsString(); string newName = FaceScriptTemplates.ProcFaceName(maidAndMan, PluginName, oldName); // Helper.Log("TagFace({0})->({1})", oldName, newName); WaitEventList waitEventList = GetWaitEventList(baseKagManager, "face"); int num = 0; if (tag_data.IsValid("wait")) { num = tag_data.GetTagProperty("wait").AsInteger(); } if (num > 0) { waitEventList.Add(() => { if (maidAndMan != null && maidAndMan.body0 != null && maidAndMan.body0.isLoadedBody) { maidAndMan.FaceAnime(newName, 1f, 0); } }, num); } else { maidAndMan.FaceAnime(newName, 1f, 0); waitEventList.Clear(); } return(false); }
/// <summary> /// エディットシーン用の状態更新 /// </summary> void EditSceneMaidUpdate(Maid maid) { if (maid == null || !maid.Visible) { return; } bool bMuhyou = ExSaveData.GetBool(maid, PluginName, "MUHYOU", false); bool bLipSyncOff = ExSaveData.GetBool(maid, PluginName, "LIPSYNC_OFF", false); if (bLipSyncOff || bMuhyou || maid.MicLipSync) { // 何もしない } else { // エディットシーンではリップシンクを強制的に復活させる Helper.SetInstanceField(typeof(Maid), maid, "m_bFoceKuchipakuSelfUpdateTime", false); } }
public void OnLevelWasLoaded(int level) { KagHooks.SetHook(PluginName, true); // TBody.MoveHeadAndEye 処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.TBody.MoveHeadAndEye.Callbacks[PluginName] = tbodyMoveHeadAndEyeCallback; // BoneMorph_.Blend 処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.BoneMorph_.Blend.Callbacks[PluginName] = boneMorph_BlendCallback; // AudioSourceMgr.Play処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.AudioSourceMgr.Play.Callbacks[PluginName] = (audioSourceMgr, f_fFadeTime, loop) => { SetAudioPitch(audioSourceMgr); }; // AudioSourceMgr.PlayOneShot処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.AudioSourceMgr.PlayOneShot.Callbacks[PluginName] = (audioSourceMgr) => { SetAudioPitch(audioSourceMgr); }; // GameMain.Deserialize処理終了後のコールバック // ロードが行われたときに呼び出される CM3D2.ExternalSaveData.Managed.GameMainCallbacks.Deserialize.Callbacks[PluginName] = (gameMain, f_nSaveNo) => { bDeserialized = true; }; // ロード直後のシーン読み込みなら、初回セットアップを行う if (bDeserialized) { bDeserialized = false; ExSaveData.CleanupMaids(); FreeComment.FreeCommentToSetting(PluginName, false); CleanupExSave(); } }
void LoadSettings(Maid maid) { if (maid == null) { return; } bool autoCam = ExSaveData.GetBool(maid, PluginName, "AutoCameraInitialValue", true); bool eyeToCam = ExSaveData.GetBool(maid, PluginName, "EyeToCameraInitialValue", true); string clothMaskMode = ExSaveData.Get(maid, PluginName, "ClothMaskMode", ""); string bgName = ExSaveData.Get(maid, PluginName, "BgName", ""); string poseName = ExSaveData.Get(maid, PluginName, "PoseName", ""); #if DEBUG Console.WriteLine( "PersonalizedEditSceneSettings.LoadSettings : name={0}{1}, autoCam={2}, eyeToCam={3}, cloth={4}, bg={5}, pose={6}", maid.Param.status.last_name, maid.Param.status.first_name, autoCam, eyeToCam, clothMaskMode, bgName, poseName); #endif editViewReset.SetVisibleAutoCam(autoCam); editViewReset.SetVisibleEyeToCam(eyeToCam); sceneEdit.ClothesState(Helper.ToEnum <SceneEditInfo.ClothesState>(clothMaskMode, SceneEditInfo.ClothesState.Wear)); SceneEdit.PVBInfo bgPvbInfo = sceneEdit.m_listBg.FirstOrDefault(i => i.info.strFileName == bgName); if (bgPvbInfo != null) { sceneEdit.Bg(bgPvbInfo); } SceneEdit.PVBInfo[] poses = sceneEdit.m_dicPose[maid.Param.status.personal]; SceneEdit.PVBInfo posePvbInfo = poses.FirstOrDefault(i => i.info.strFileName + ".anm" == poseName); if (posePvbInfo != null) { sceneEdit.Pose(posePvbInfo); } LoadCameraSettings(maid); }
void OnSceneLoaded(Scene scene, LoadSceneMode mode) { KagHooks.SetHook(PluginName, true); // TBody.MoveHeadAndEye 処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.TBody.MoveHeadAndEye.Callbacks[PluginName] = tbodyMoveHeadAndEyeCallback; // BoneMorph_.Blend 処理終了後のコールバック CM3D2.MaidVoicePitch.Managed.Callbacks.BoneMorph_.Blend.Callbacks[PluginName] = boneMorph_BlendCallback; // GameMain.Deserialize処理終了後のコールバック // ロードが行われたときに呼び出される CM3D2.ExternalSaveData.Managed.GameMainCallbacks.Deserialize.Callbacks[PluginName] = (gameMain, f_nSaveNo) => { bDeserialized = true; }; // スカート計算用コールバック CM3D2.MaidVoicePitch.Managed.Callbacks.DynamicSkirtBone.PreUpdateSelf.Callbacks[PluginName] = DynamicSkirtBonePreUpdate; CM3D2.MaidVoicePitch.Managed.Callbacks.DynamicSkirtBone.PostUpdateSelf.Callbacks[PluginName] = DynamicSkirtBonePostUpdate; // 胸ボーンサイズ調整用コールバック CM3D2.MaidVoicePitch.Managed.Callbacks.jiggleBone.PreLateUpdateSelf.Callbacks[PluginName] = jiggleBonePreLateUpdateSelef; CM3D2.MaidVoicePitch.Managed.Callbacks.jiggleBone.PostLateUpdateSelf.Callbacks[PluginName] = jiggleBonePostLateUpdateSelef; CM3D2.MaidVoicePitch.Managed.Callbacks.CharacterMgr.PresetSet.Callbacks[PluginName] = CharacterMgrPresetSet; // ロード直後のシーン読み込みなら、初回セットアップを行う if (bDeserialized) { bDeserialized = false; ExSaveData.CleanupMaids(); CleanupExSave(); } SliderTemplates.Clear(); }
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); }
public static void FreeCommentToSetting(Maid maid, string PluginName, bool overwrite) { if (maid == null || maid.Param == null || maid.Param.status == null) { return; } string freeComment = maid.Param.status.free_comment; Func <string, bool> Contains = (str) => { if (freeComment == null) { return(false); } return(freeComment.Contains(str)); }; Func <string, string> String = (pattern) => { if (freeComment != null) { Match m = Regex.Match(freeComment, pattern); if (m.Groups.Count >= 2) { return(m.Groups[1].Value); } } return(null); }; Func <int, float, string, float> Float = (index, defaultValue, pattern) => { if (freeComment != null) { Match m = Regex.Match(freeComment, pattern); if (m.Groups.Count >= 2 + index) { return(Helper.StringToFloat(m.Groups[1 + index].Value, defaultValue)); } } return(defaultValue); }; string n = PluginName; // ExSaveData.SetBool(maid, n, "WIDESLIDER", Contains("#WIDESLIDER#") || Contains("#TEST_WIDE_SLIDER#"), overwrite); ExSaveData.SetBool(maid, n, "PROPSET_OFF", Contains("#PROPSET_OFF#") || Contains("#TEST_PROPSET_OFF#"), overwrite); ExSaveData.SetFloat(maid, n, "EYETOCAM", Contains("#EYETOCAM#") ? 1f : 0f, overwrite); ExSaveData.SetFloat(maid, n, "HEADTOCAM", Contains("#HEADTOCAM#") ? 1f : 0f, overwrite); ExSaveData.SetBool(maid, n, "LIPSYNC_OFF", Contains("#LIPSYNC_OFF#"), overwrite); ExSaveData.SetBool(maid, n, "HYOUJOU_OFF", Contains("#HYOUJOU_OFF#"), overwrite); ExSaveData.SetBool(maid, n, "EYETOCAMERA_OFF", Contains("#TEST_EYETOCAMERA_OFF#"), overwrite); ExSaveData.SetBool(maid, n, "MUHYOU", Contains("#MUHYOU#"), overwrite); ExSaveData.Set(maid, n, "FACE_SCRIPT_TEMPLATE", String(@"#TEST_FACE_SCRIPT_TEMPLATE=([^#]*)#"), overwrite); ExSaveData.SetFloat(maid, n, "FACE_ANIME_SPEED", Float(0, 1f, @"#TEST_FACE_ANIME_SPEED=([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.Set(maid, n, "SLIDER_TEMPLATE", String(@"#TEST_SLIDER_TEMPLATE=([^#]*)#"), overwrite); ExSaveData.SetFloat(maid, n, "PITCH", Float(0, 0f, @"#PITCH=([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "LIPSYNC", Float(0, 1f, @"#TEST_LIPSYNC=([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYEBALL.width", Float(0, 1f, @"#EYEBALL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYEBALL.height", Float(1, 1f, @"#EYEBALL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYE_RATIO", Float(0, 1f, @"#TEST_EYE_RATIO=([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "MABATAKI", Float(0, 1f, @"#MABATAKI=([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "MABATAKI.pause", Contains("#MABATAKI_PAUSE#"), overwrite); // ExSaveData.SetFloat(maid, n, "MABATAKI.min", Float(0, 0f, @"#MABATAKI=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); // ExSaveData.SetFloat(maid, n, "MABATAKI.max", Float(1, 1f, @"#MABATAKI=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYE_ANG.angle", Float(0, 0f, @"#TEST_EYE_ANG=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYE_ANG.x", Float(1, 0f, @"#TEST_EYE_ANG=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "EYE_ANG.y", Float(2, 0f, @"#TEST_EYE_ANG=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "PELSCL.width", Float(0, 1f, @"#TEST_PELSCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "PELSCL.depth", Float(1, 1f, @"#TEST_PELSCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "PELSCL.height", Float(2, 1f, @"#TEST_PELSCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "THISCL.width", Float(0, 1f, @"#TEST_THISCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "THISCL.depth", Float(1, 1f, @"#TEST_THISCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "THIPOS.x", Float(0, 0f, @"#TEST_THIPOS=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "THIPOS.z", Float(1, 0f, @"#TEST_THIPOS=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "PELVIS", Contains("#TEST_PELVIS_ENABLE#"), overwrite); ExSaveData.SetFloat(maid, n, "PELVIS.x", Float(0, 0f, @"#TEST_PELVIS=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "PELVIS.y", Float(1, 0f, @"#TEST_PELVIS=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "PELVIS.z", Float(2, 0f, @"#TEST_PELVIS=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "FARMFIX", Contains("#FARMFIX##"), overwrite); ExSaveData.SetBool(maid, n, "SPISCL", Contains("#SPISCL"), overwrite); ExSaveData.SetFloat(maid, n, "SPISCL.width", Float(0, 1f, @"#SPISCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "SPISCL.depth", Float(1, 1f, @"#SPISCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "SPISCL.height", Float(2, 1f, @"#SPISCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "S0ASCL", Contains("#S0ASCL"), overwrite); ExSaveData.SetFloat(maid, n, "S0ASCL.width", Float(0, 1f, @"#S0ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S0ASCL.depth", Float(1, 1f, @"#S0ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S0ASCL.height", Float(2, 1f, @"#S0ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "S1_SCL", Contains("#S1_SCL"), overwrite); ExSaveData.SetFloat(maid, n, "S1_SCL.width", Float(0, 1f, @"#S1_SCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S1_SCL.depth", Float(1, 1f, @"#S1_SCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S1_SCL.height", Float(2, 1f, @"#S1_SCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetBool(maid, n, "S1ASCL", Contains("#S1ASCL"), overwrite); ExSaveData.SetFloat(maid, n, "S1ASCL.width", Float(0, 1f, @"#S1ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S1ASCL.depth", Float(1, 1f, @"#S1ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); ExSaveData.SetFloat(maid, n, "S1ASCL.height", Float(2, 1f, @"#S1ASCL=([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)#"), overwrite); }
// スライダー範囲を拡大 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); } } }
static TemplateFile Get(Maid maid, string PluginName) { return(Get(ExSaveData.Get(maid, PluginName, "FACE_SCRIPT_TEMPLATE", null))); }
// 新しい 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 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); } }
// スライダー範囲を拡大 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); } }