using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public class TMorph { public TMorph(TBodySkin bs) { this.bodyskin = bs; this.Category = bs.Category; this.SlotId = bs.SlotId; this.hash = new Hashtable(); this.MorphCount = 0; this.BlendDatas = new List(20); this.BoneNames = new List(200); this.BoneVisible = new List(200); } public float LipSync1 { get { return this.m_LipSync1; } set { this.m_LipSync1 = Mathf.Clamp01(value); } } public float LipSync2 { get { return this.m_LipSync2; } set { this.m_LipSync2 = Mathf.Clamp01(value); } } public float LipSync3 { get { return this.m_LipSync3; } set { this.m_LipSync3 = Mathf.Clamp01(value); } } ~TMorph() { this.DeleteObj(); } public BlendData this[string tag] { get { int index = (int)this.hash[tag]; return this.BlendDatas[index]; } } public bool Contains(string name) { return this.hash.ContainsKey(name); } public float GetBlendValues(int f_nIdx) { return this.BlendValues[f_nIdx]; } public void SetBlendValues(int f_nIdx, float f_fValue) { float[] blendValuesBackup = this.BlendValuesBackup; this.BlendValues[f_nIdx] = f_fValue; blendValuesBackup[f_nIdx] = f_fValue; } public void DeleteObj() { this.bodyskin = null; this.m_mesh = null; this.smr_src = null; this.m_bones = null; this.m_vOriVert = null; this.m_vOriNorm = null; this.m_nSubMeshOriTri = null; this.m_bws = null; } public unsafe void InitGameObject(GameObject o) { SkinnedMeshRenderer skinnedMeshRenderer = null; List list = new List(3); o.GetComponentsInChildren(true, list); for (int i = 0; i < list.Count; i++) { skinnedMeshRenderer = list[i]; } Transform[] bones = skinnedMeshRenderer.bones; Transform transform = o.transform; this.tRoot = transform; if (skinnedMeshRenderer == null) { Debug.LogError("err init morph " + o.name); this.initlp(this.tRoot); return; } this.smr_src = skinnedMeshRenderer; this.m_bones = bones; this.m_mesh = this.smr_src.sharedMesh; this.VCount = this.bodyskin.m_OriVert.VCount; this.m_vOriVert = this.bodyskin.m_OriVert.vOriVert; this.m_vOriNorm = this.bodyskin.m_OriVert.vOriNorm; this.m_vTmpVert = new Vector3[this.VCount]; this.m_vTmpNorm = new Vector3[this.VCount]; this.m_AtrVert = new int[this.VCount]; this.m_vOriVert.CopyTo(this.m_vTmpVert, 0); this.m_vOriNorm.CopyTo(this.m_vTmpNorm, 0); this.m_nSubMeshCount = this.bodyskin.m_OriVert.nSubMeshCount; this.m_nSubMeshOriTri = this.bodyskin.m_OriVert.nSubMeshOriTri; this.m_nSubMeshTmpTri = new int[this.m_nSubMeshCount][]; for (int j = 0; j < this.m_nSubMeshCount; j++) { int[] array = this.m_nSubMeshOriTri[j]; this.m_nSubMeshTmpTri[j] = new int[array.Length]; } this.BoneCount = this.m_bones.Length; this.initlp(this.tRoot); this.m_fFaceShapeRate = 0f; if (this.hash.ContainsKey("shape")) { this.m_BlendDataIdx_FaceShape = (int)this.hash["shape"]; } this.m_fEyeCloseRate = 0f; this.BlendDataIdx_EyeClose = new int[10]; if (this.hash.ContainsKey("eyeclose")) { this.BlendDataIdx_EyeClose[0] = (int)this.hash["eyeclose"]; } for (int k = 1; k < 10; k++) { if (this.hash.ContainsKey("eyeclose" + k.ToString())) { this.BlendDataIdx_EyeClose[k] = (int)this.hash["eyeclose" + k.ToString()]; } } if (!this.bodyskin.body.boMAN && this.Category == "head" && this.BlendDataIdx_EyeClose[0] == 0) { Debug.LogError("Face[eyeclose]"); } if (this.hash.ContainsKey("toothoff")) { this.BlendDataIdx_LipSyncTh = (int)this.hash["toothoff"]; } if (this.hash.ContainsKey("moutha")) { this.BlendDataIdx_LipSync_A = (int)this.hash["moutha"]; } if (this.hash.ContainsKey("mouths")) { this.BlendDataIdx_LipSync_S = (int)this.hash["mouths"]; } if (this.hash.ContainsKey("mouthc")) { this.BlendDataIdx_LipSync_C = (int)this.hash["mouthc"]; } if (this.hash.ContainsKey("toothoff")) { this.BlendDataIdx_LipSync_ToothOFF = (int)this.hash["toothoff"]; } if (this.hash.ContainsKey("mouthdw")) { this.BlendDataIdx_LipSync_W = (int)this.hash["mouthdw"]; } if (this.hash.ContainsKey("tear1")) { this.BlendDataIdx_Tear1 = (int)this.hash["tear1"]; } if (this.hash.ContainsKey("tear2")) { this.BlendDataIdx_Tear2 = (int)this.hash["tear2"]; } if (this.hash.ContainsKey("tear3")) { this.BlendDataIdx_Tear3 = (int)this.hash["tear3"]; } if (this.hash.ContainsKey("nosefook")) { this.BlendDataIdx_NoseFook = (int)this.hash["nosefook"]; } if (this.hash.ContainsKey("eyeclose")) { int count = this.BlendDatas.Count; this.hash["uru-uru"] = count; this.BlendDatas.Add(null); this.MorphCount++; } if (this.hash.ContainsKey("regfat")) { this.BlendDataIdx_RegFat = (int)this.hash["regfat"]; } if (this.hash.ContainsKey("regmeet")) { this.BlendDataIdx_RegMeet = (int)this.hash["regmeet"]; } this.ScrnV = new Vector3[this.VCount]; this.WorldV = new Vector3[this.VCount]; this.BindVert = new Vector3[this.VCount]; this.DefVert = new Vector3[this.VCount]; this.BindBone = new int[this.VCount]; this.m_bindposes = this.m_mesh.bindposes; this.m_bws = this.bodyskin.m_OriVert.bwWeight; fixed (BoneWeight* ptr = &this.m_bws[0]) { BoneWeight* ptr2 = ptr; for (int l = 0; l < this.VCount; l++) { int num = ptr2->boneIndex0; float num2 = ptr2->weight0; if (ptr2->weight1 > num2) { num2 = ptr2->weight1; num = ptr2->boneIndex1; } if (ptr2->weight2 > num2) { num2 = ptr2->weight2; num = ptr2->boneIndex2; } if (ptr2->weight3 > num2) { num2 = ptr2->weight3; num = ptr2->boneIndex3; } this.BindBone[l] = num; Vector3 vector = this.m_bindposes[num].MultiplyPoint3x4(this.m_vOriVert[l]); this.BindVert[l] = vector; this.DefVert[l] = this.m_bones[num].TransformPoint(vector); this.m_AtrVert[l] = 0; for (int m = 0; m < TMorph.AtrVertChk.Length; m++) { if (this.BoneNames[ptr2->boneIndex0].Contains(TMorph.AtrVertChk[m])) { this.m_AtrVert[l] |= 1 << m; } if (ptr2->weight1 > 0f && this.BoneNames[ptr2->boneIndex1].Contains(TMorph.AtrVertChk[m])) { this.m_AtrVert[l] |= 1 << m; } if (ptr2->weight2 > 0f && this.BoneNames[ptr2->boneIndex2].Contains(TMorph.AtrVertChk[m])) { this.m_AtrVert[l] |= 1 << m; } if (ptr2->weight3 > 0f && this.BoneNames[ptr2->boneIndex3].Contains(TMorph.AtrVertChk[m])) { this.m_AtrVert[l] |= 1 << m; } } ptr2++; } } } private void initlp(Transform t) { for (int i = 0; i < this.BoneCount; i++) { if (this.m_bones[i] != null) { this.BoneNames.Add(this.m_bones[i].name); this.BoneVisible.Add(true); } else { this.BoneNames.Add(string.Empty); this.BoneVisible.Add(false); } } this.m_bDut = false; } public void ClearAllVisibleFlag(bool boSetFlag) { for (int i = 0; i < this.BoneCount; i++) { if (this.BoneVisible[i] != boSetFlag) { this.BoneVisible[i] = boSetFlag; this.m_bDut = true; } } } public void SetVisibleFlag1(int idx, bool flag) { if (this.BoneVisible[idx] != flag) { this.BoneVisible[idx] = flag; this.m_bDut = true; } } public void SetVisibleFlag(bool boSetFlag, string name, Transform t = null, bool boTgt = false, int cnt = -1) { cnt++; if (t == null) { t = this.tRoot; } if (t.name.IndexOf(name) >= 0) { boTgt = true; } if (name == "_ALL_") { boTgt = true; } if (boTgt) { for (int i = 0; i < this.BoneCount; i++) { if (t.name == this.BoneNames[i]) { this.SetVisibleFlag1(i, boSetFlag); break; } } } for (int j = 0; j < t.childCount; j++) { this.SetVisibleFlag(boSetFlag, name, t.GetChild(j), boTgt, cnt); } } public void FixVisibleFlag() { if (this.smr_src == null) { return; } if (this.m_mesh == null) { return; } if (!this.m_bDut) { return; } for (int i = 0; i < this.m_nSubMeshCount; i++) { this.m_nSubMeshOriTri[i].CopyTo(this.m_nSubMeshTmpTri[i], 0); int[] array = this.m_nSubMeshTmpTri[i]; for (int j = 0; j < array.Length / 3; j++) { int num = 3; for (int k = 0; k < 3; k++) { int num2 = array[j * 3 + k]; BoneWeight boneWeight = this.m_bws[num2]; if (!this.BoneVisible[boneWeight.boneIndex0]) { num--; break; } if (!this.BoneVisible[boneWeight.boneIndex1] && boneWeight.weight1 > 0f) { num--; break; } if (!this.BoneVisible[boneWeight.boneIndex2] && boneWeight.weight2 > 0f) { num--; break; } if (!this.BoneVisible[boneWeight.boneIndex3] && boneWeight.weight3 > 0f) { num--; break; } } if (num != 3) { for (int l = 0; l < 3; l++) { array[j * 3 + l] = 0; } } } this.m_mesh.SetTriangles(array, i); } this.m_bDut = false; } public void LoadMoprhData2(BinaryReader r) { string text = r.ReadString(); int count = this.BlendDatas.Count; this.hash[text] = count; BlendData blendData = new BlendData(); blendData.name = text; int num = r.ReadInt32(); blendData.vert = new Vector3[num]; blendData.norm = new Vector3[num]; blendData.v_index = new int[num]; for (int i = 0; i < num; i++) { blendData.v_index[i] = (int)r.ReadUInt16(); blendData.vert[i].x = r.ReadSingle(); blendData.vert[i].y = r.ReadSingle(); blendData.vert[i].z = r.ReadSingle(); blendData.norm[i].x = r.ReadSingle(); blendData.norm[i].y = r.ReadSingle(); blendData.norm[i].z = r.ReadSingle(); } this.MorphCount++; this.BlendDatas.Add(blendData); this.BlendValues = new float[this.MorphCount + 1]; this.BlendValuesTemp = new float[this.MorphCount + 1]; this.BlendValuesBackup = new float[this.MorphCount + 1]; this.BlendValuesCHK = new float[this.MorphCount + 1]; } public void NewBlendSet(string BlendSetName) { float[] array = new float[this.hash.Count]; for (int i = 0; i < array.Length; i++) { array[i] = 0f; } if (this.dicBlendSet.ContainsKey(BlendSetName)) { Debug.LogError("\u0093ブレンドセット" + BlendSetName); } this.dicBlendSet[BlendSetName] = array; this.dicBlendAtr[BlendSetName] = 0; if (!this.dicBlendSet.ContainsKey("オリジナル")) { float[] array2 = new float[this.hash.Count]; for (int j = 0; j < array2.Length; j++) { array2[j] = 0f; } this.dicBlendSet["オリジナル"] = array2; } } public void SetValueOriginalBlendSet(TMorph.AddBlendType add_blend_type_flag) { float[] array = this.dicBlendSet["オリジナル"]; array[(int)this.hash["hohol"]] = (array[(int)this.hash["hoho"]] = (array[(int)this.hash["hohos"]] = 0f)); if ((add_blend_type_flag & TMorph.AddBlendType.Cheek3) == TMorph.AddBlendType.Cheek3) { array[(int)this.hash["hohol"]] = 1f; } else if ((add_blend_type_flag & TMorph.AddBlendType.Cheek2) == TMorph.AddBlendType.Cheek2) { array[(int)this.hash["hoho"]] = 1f; } else if ((add_blend_type_flag & TMorph.AddBlendType.Cheek1) == TMorph.AddBlendType.Cheek1) { array[(int)this.hash["hohos"]] = 1f; } array[(int)this.hash["tear3"]] = (array[(int)this.hash["tear2"]] = (array[(int)this.hash["tear1"]] = 0f)); if ((add_blend_type_flag & TMorph.AddBlendType.Tear3) == TMorph.AddBlendType.Tear3) { array[(int)this.hash["tear3"]] = 1f; } else if ((add_blend_type_flag & TMorph.AddBlendType.Tear2) == TMorph.AddBlendType.Tear2) { array[(int)this.hash["tear2"]] = 1f; } else if ((add_blend_type_flag & TMorph.AddBlendType.Tear1) == TMorph.AddBlendType.Tear1) { array[(int)this.hash["tear1"]] = 1f; } array[(int)this.hash["hoho2"]] = (float)(((add_blend_type_flag & TMorph.AddBlendType.Blush) != TMorph.AddBlendType.Blush) ? 0 : 1); array[(int)this.hash["namida"]] = (float)(((add_blend_type_flag & TMorph.AddBlendType.TearBig) != TMorph.AddBlendType.TearBig) ? 0 : 1); array[(int)this.hash["yodare"]] = (float)(((add_blend_type_flag & TMorph.AddBlendType.Yodare) != TMorph.AddBlendType.Yodare) ? 0 : 1); array[(int)this.hash["shock"]] = (float)(((add_blend_type_flag & TMorph.AddBlendType.Shock) != TMorph.AddBlendType.Shock) ? 0 : 1); } public void SetValueBlendSet(string BlendSetName, string tag, float val) { if (tag == "hoho2") { Dictionary dictionary = this.dicBlendAtr; int value = (this.dicBlendAtr[BlendSetName] & -4) | 2; this.dicBlendAtr[BlendSetName] = value; dictionary[BlendSetName] = value; } if (tag == "hoho" && (this.dicBlendAtr[BlendSetName] & 3) != 1) { this.dicBlendAtr[BlendSetName] = ((this.dicBlendAtr[BlendSetName] & -4) | 1); } if (!this.dicBlendSet.ContainsKey(BlendSetName)) { Debug.LogError("表情がありません。" + BlendSetName); return; } if (!this.hash.Contains(tag)) { Debug.LogError("表情がありません。tag=" + tag); return; } int num = (int)this.hash[tag]; if (tag == "hoho2") { this.IdxHOHO2 = num; } if (tag == "hoho") { this.IdxHOHO = num; } this.dicBlendSet[BlendSetName][num] = val * 0.01f; } public void ClearBlendValues() { for (int i = 0; i < this.MorphCount; i++) { this.BlendValuesBackup[i] = (this.BlendValues[i] = 0f); } } public void MulBlendValues(string BlendSetName, float mul = 1f) { if (this.dicBlendSet.ContainsKey(BlendSetName)) { float[] array = this.dicBlendSet[BlendSetName]; for (int i = 0; i < this.MorphCount; i++) { this.BlendValuesBackup[i] = (this.BlendValues[i] = this.BlendValues[i] * (1f - mul) + array[i] * mul); } return; } if (BlendSetName == "頬0涙0") { return; } Debug.LogError("表情がありません。" + BlendSetName); } public void AddBlendValues(string BlendSetName, float add = 1f) { if (this.dicBlendSet.ContainsKey(BlendSetName)) { float[] array = this.dicBlendSet[BlendSetName]; for (int i = 0; i < this.MorphCount; i++) { this.BlendValues[i] += array[i] * add; if (this.BlendValues[i] > 1f) { this.BlendValues[i] = 1f; } this.BlendValuesBackup[i] = this.BlendValues[i]; } return; } if (BlendSetName == "頬0涙0") { return; } Debug.LogError("表情がありません。" + BlendSetName); } public void FixBlendValues_Face() { this.BlendValuesTemp[this.BlendDataIdx_EyeClose[0]] = this.m_fEyeCloseRate + this.BlendValuesBackup[this.BlendDataIdx_EyeClose[0]] * (1f - this.m_fEyeCloseRate); for (int i = 1; i < 10; i++) { if (this.BlendDataIdx_EyeClose[i] != 0) { this.BlendValuesTemp[this.BlendDataIdx_EyeClose[i]] = this.BlendValuesBackup[this.BlendDataIdx_EyeClose[i]] * (1f - this.m_fEyeCloseRate); } } if (0f < this.EyeMabataki) { float num = 0f; for (int j = 0; j < 10; j++) { if (this.BlendDataIdx_EyeClose[j] != 0) { num += this.BlendValuesTemp[this.BlendDataIdx_EyeClose[j]]; } } if (num > 1f) { num = 1f; } float num2 = 1f - num; float num3 = this.BlendValuesTemp[this.BlendDataIdx_EyeClose[0]] + num2 * this.EyeMabataki; if (num3 > 0f) { this.BlendValuesTemp[this.BlendDataIdx_EyeClose[0]] = num3; } } for (int k = 0; k < 10; k++) { if (this.BlendDataIdx_EyeClose[k] != 0) { this.BlendValues[this.BlendDataIdx_EyeClose[k]] = this.BlendValuesTemp[this.BlendDataIdx_EyeClose[k]]; } } if (this.m_BlendDataIdx_FaceShape != -1) { this.BlendValues[this.m_BlendDataIdx_FaceShape] = this.m_fFaceShapeRate; } if (this.boLipSync) { this.BlendValues[this.BlendDataIdx_LipSync_A] = this.LipSync1 * 0.8f; this.BlendValues[this.BlendDataIdx_LipSync_C] = this.LipSync3 * 0.7f; this.BlendValues[this.BlendDataIdx_LipSync_ToothOFF] = this.LipSync3; this.BlendValues[this.BlendDataIdx_LipSync_S] = this.LipSync2 * (1f - this.LipSync1) * 0.5f; this.BlendValues[this.BlendDataIdx_LipSync_W] = this.LipSync2 * 0.3f; this.BlendValues[this.BlendDataIdx_LipSyncTh] = 0.5f; } if (this.boLookTooth) { this.BlendValues[this.BlendDataIdx_LipSync_A] = 0f; this.BlendValues[this.BlendDataIdx_LipSync_S] = 0.7f; this.BlendValues[this.BlendDataIdx_LipSync_C] = 0f; this.BlendValues[this.BlendDataIdx_LipSyncTh] = 0f; } if (this.boBallGAG) { this.BlendValues[this.BlendDataIdx_LipSync_A] = 1f; this.BlendValues[this.BlendDataIdx_LipSync_S] = 0f; this.BlendValues[this.BlendDataIdx_LipSync_C] = 0f; this.BlendValues[this.BlendDataIdx_LipSyncTh] = 0f; } float num4 = this.BlendValues[this.BlendDataIdx_Tear3]; if (this.BlendValues[this.BlendDataIdx_Tear2] + num4 > 1f) { this.BlendValues[this.BlendDataIdx_Tear2] = 1f - num4; num4 = 1f; } else { num4 += this.BlendValues[this.BlendDataIdx_Tear2]; } if (this.BlendValues[this.BlendDataIdx_Tear1] + num4 > 1f) { this.BlendValues[this.BlendDataIdx_Tear1] = 1f - num4; } if (this.boNoseFook) { this.BlendValues[this.BlendDataIdx_NoseFook] = 1f; } else { this.BlendValues[this.BlendDataIdx_NoseFook] = 0f; } int num5 = 0; for (int l = 0; l < this.MorphCount; l++) { if (this.BlendValuesCHK[l] != this.BlendValues[l]) { num5++; this.BlendValuesCHK[l] = this.BlendValues[l]; } } if (num5 == 0) { return; } this.m_vOriVert.CopyTo(this.m_vTmpVert, 0); this.m_bMorph = true; if (this.BlendValues[this.IdxHOHO] < 0.5f) { this.BlendValues[this.IdxHOHO] = 0f; } else { this.BlendValues[this.IdxHOHO] = 1f; } if (this.BlendValues[this.IdxHOHO2] < 0.5f) { this.BlendValues[this.IdxHOHO2] = 0f; } else { this.BlendValues[this.IdxHOHO2] = 1f; } for (int m = 0; m < this.MorphCount; m++) { if (this.BlendDatas[m] == null) { this.UruUruScaleX = this.BlendValues[m]; } else { float num6 = this.BlendValues[m]; if (num6 >= 0.01f) { int num7 = this.BlendDatas[m].v_index.Length; for (int n = 0; n < num7; n++) { int num8 = this.BlendDatas[m].v_index[n]; this.m_vTmpVert[num8] += this.BlendDatas[m].vert[n] * num6; } } } } this.m_mesh.vertices = this.m_vTmpVert; foreach (TAttachPoint tattachPoint in this.dicAttachPoint.Values) { int vidx = tattachPoint.vidx; Vector3 vector = Vector3.zero; vector += this.m_bindposes[tattachPoint.bw.boneIndex0].MultiplyPoint3x4(this.m_vTmpVert[vidx]) * tattachPoint.bw.weight0; vector += this.m_bindposes[tattachPoint.bw.boneIndex1].MultiplyPoint3x4(this.m_vTmpVert[vidx]) * tattachPoint.bw.weight1; vector += this.m_bindposes[tattachPoint.bw.boneIndex2].MultiplyPoint3x4(this.m_vTmpVert[vidx]) * tattachPoint.bw.weight2; vector += this.m_bindposes[tattachPoint.bw.boneIndex3].MultiplyPoint3x4(this.m_vTmpVert[vidx]) * tattachPoint.bw.weight3; this.BindVert[vidx] = vector; } } public void FixFixBlendValues() { IEnumerator enumerator = this.hash.Keys.GetEnumerator(); try { while (enumerator.MoveNext()) { object obj = enumerator.Current; string text = (string)obj; int num = (int)this.hash[text]; MaidProp propLower = this.bodyskin.body.maid.GetPropLower(text); if (propLower != null) { this.BlendValues[num] = (float)propLower.value / 100f; this.FixBlendValues(); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } } public void FixBlendValues() { int num = 0; for (int i = 0; i < this.MorphCount; i++) { if (this.BlendValuesCHK[i] != this.BlendValues[i]) { num++; this.BlendValuesCHK[i] = this.BlendValues[i]; } } if (num == 0) { return; } this.m_vOriVert.CopyTo(this.m_vTmpVert, 0); this.m_vOriNorm.CopyTo(this.m_vTmpNorm, 0); this.m_bMorph = true; for (int j = 0; j < this.MorphCount; j++) { if (this.BlendDatas[j] == null) { this.UruUruScaleX = this.BlendValues[j]; } else { float num2 = this.BlendValues[j]; if (num2 >= 0.01f) { int num3 = this.BlendDatas[j].v_index.Length; for (int k = 0; k < num3; k++) { int num4 = this.BlendDatas[j].v_index[k]; this.m_vTmpVert[num4] += this.BlendDatas[j].vert[k] * num2; this.m_vTmpNorm[num4] += this.BlendDatas[j].norm[k] * num2; } } } } this.m_mesh.vertices = this.m_vTmpVert; this.m_mesh.normals = this.m_vTmpNorm; foreach (TAttachPoint tattachPoint in this.dicAttachPoint.Values) { int vidx = tattachPoint.vidx; this.BindVert[vidx] = this.m_bindposes[tattachPoint.bw.boneIndex0].MultiplyPoint3x4(this.m_vTmpVert[vidx]); } } public void ResetBlendValues() { if (this.m_bMorph) { this.m_mesh.vertices = this.m_vTmpVert; this.m_mesh.normals = this.m_vTmpNorm; } } public void SetEnableAttachPointEdit(bool f_bEnable, string f_strApName) { TAttachPoint tattachPoint = this.dicAttachPoint[f_strApName]; if (tattachPoint.bEditable == f_bEnable) { return; } int num = tattachPoint.srcvidx; Vector3 vector = Vector3.zero; Vector3 vector2 = Vector3.one; Quaternion quaternion = tattachPoint.qSrc; VtxAttachPos attachPointPos = this.bodyskin.body.maid.GetAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, this.m_vOriVert.Length, f_strApName); if (attachPointPos != null) { num = attachPointPos.vidx; vector = attachPointPos.prs.position; quaternion = attachPointPos.prs.rotation; vector2 = attachPointPos.prs.scale; } if (f_bEnable) { tattachPoint.vidx = num; tattachPoint.vOffsLocal = vector; tattachPoint.qNow = quaternion; tattachPoint.vScaleRate = vector2; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; } else { tattachPoint.vidx = tattachPoint.srcvidx; tattachPoint.vOffsLocal = Vector3.zero; tattachPoint.qNow = tattachPoint.qSrc; tattachPoint.vScaleRate = Vector3.one; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; } tattachPoint.bEditable = f_bEnable; this.bodyskin.body.maid.SetAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, this.m_vOriVert.Length, f_strApName, num, vector, quaternion, vector2, tattachPoint.bEditable); } public bool GetEnableAttachPointEdit(string f_strApName) { return this.dicAttachPoint[f_strApName].bEditable; } public void SetAttachPoint(string apname, Vector3 vc, Quaternion q, bool f_bTemp) { TAttachPoint tattachPoint = new TAttachPoint(); float num = (vc - this.DefVert[0]).sqrMagnitude; int num2 = 0; for (int i = 0; i < this.m_vOriVert.Length; i++) { float sqrMagnitude = (vc - this.DefVert[i]).sqrMagnitude; if (num > sqrMagnitude) { num = sqrMagnitude; num2 = i; } } tattachPoint.srcvidx = (tattachPoint.vidx = num2); tattachPoint.vOffsLocal = Vector3.zero; TAttachPoint tattachPoint2 = tattachPoint; tattachPoint.qNow = q; tattachPoint2.qSrc = q; tattachPoint.vScaleRate = Vector3.one; tattachPoint.bw = this.m_bws[num2]; this.dicAttachPoint[apname] = tattachPoint; if (!f_bTemp) { VtxAttachPos attachPointPos = this.bodyskin.body.maid.GetAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, this.m_vOriVert.Length, apname); if (attachPointPos != null && attachPointPos.bEnable) { tattachPoint.vidx = attachPointPos.vidx; tattachPoint.vOffsLocal = attachPointPos.prs.position; tattachPoint.qNow = attachPointPos.prs.rotation; tattachPoint.vScaleRate = attachPointPos.prs.scale; tattachPoint.bEditable = true; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; } } } public void SetAttachPointOffsetLocal(string apname, VtxAttachPos f_vap) { TAttachPoint tattachPoint = this.dicAttachPoint[apname]; tattachPoint.vidx = f_vap.vidx; tattachPoint.vOffsLocal = f_vap.prs.position; tattachPoint.qNow = f_vap.prs.rotation; tattachPoint.vScaleRate = f_vap.prs.scale; tattachPoint.bEditable = true; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; } public bool CopyAttachObjPoint(string apname) { TAttachPoint tattachPoint = this.dicAttachPoint[apname]; TMorph.TempAttachPos tempAttachPos = new TMorph.TempAttachPos(); tempAttachPos.m_nVidx = tattachPoint.vidx; tempAttachPos.m_vPos = tattachPoint.vOffsLocal; tempAttachPos.m_qRot = tattachPoint.qNow; tempAttachPos.m_vScale = tattachPoint.vScaleRate; this.bodyskin.m_dicTempAttachPoint[apname] = tempAttachPos; return true; } public bool PastAttachObjPoint(string apname) { TAttachPoint tattachPoint = this.dicAttachPoint[apname]; TMorph.TempAttachPos tempAttachPos = null; if (this.bodyskin.m_dicTempAttachPoint.TryGetValue(apname, out tempAttachPos)) { tattachPoint.bEditable = true; tattachPoint.vidx = tempAttachPos.m_nVidx; tattachPoint.vOffsLocal = tempAttachPos.m_vPos; tattachPoint.qNow = tempAttachPos.m_qRot; tattachPoint.vScaleRate = tempAttachPos.m_vScale; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; } this.bodyskin.body.maid.SetAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, this.m_vOriVert.Length, apname, tattachPoint.vidx, tattachPoint.vOffsLocal, tattachPoint.qNow, tattachPoint.vScaleRate, tattachPoint.bEditable); return true; } public void SetAttachPointWorld(string apname, Vector3 vWorldPos, Quaternion qWorldRot, Vector3 vScaleRate) { TAttachPoint tattachPoint = this.dicAttachPoint[apname]; if (!tattachPoint.bEditable) { return; } this.ReclucPointWorldAndScreen(null); int vidx = tattachPoint.vidx; float num = (this.WorldV[vidx] - vWorldPos).sqrMagnitude; int num2 = vidx; for (int i = 0; i < this.m_vOriVert.Length; i++) { float sqrMagnitude = (this.WorldV[i] - vWorldPos).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; num2 = i; } } tattachPoint.vidx = num2; tattachPoint.bw = this.m_bws[num2]; int num3 = this.BindBone[num2]; Transform transform = this.m_bones[num3].transform; Vector3 vector = Vector3.zero; if (this.SlotId == TBody.SlotID.body) { this.CalcVertexPoint(ref vector, num2, ref tattachPoint.bw); } else { vector = this.BindVert[num2]; vector = transform.TransformPoint(vector); tattachPoint.vOffsLocal = transform.InverseTransformPoint(vWorldPos) - transform.InverseTransformPoint(vector); } tattachPoint.qNow = Quaternion.Inverse(transform.transform.rotation) * qWorldRot; tattachPoint.vScaleRate = vScaleRate; this.dicAttachPoint[apname] = tattachPoint; this.bodyskin.body.maid.SetAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, this.m_vOriVert.Length, apname, tattachPoint.vidx, tattachPoint.vOffsLocal, tattachPoint.qNow, tattachPoint.vScaleRate, tattachPoint.bEditable); Debug.DrawLine(vector, vWorldPos, Color.cyan); } public bool GetAttachPoint(string apname, out Vector3 vWorldPos, out Quaternion qWorldRot, out Vector3 vScaleRate, bool f_bTemp = false) { if (!this.dicAttachPoint.ContainsKey(apname)) { vWorldPos = Vector3.zero; qWorldRot = Quaternion.identity; vScaleRate = Vector3.one; return false; } TAttachPoint tattachPoint = this.dicAttachPoint[apname]; Vector3 vector = Vector3.zero; int num = tattachPoint.vidx; if (f_bTemp) { num = tattachPoint.srcvidx; } Transform transform = this.m_bones[this.BindBone[num]].transform; if (this.SlotId == TBody.SlotID.body) { this.CalcVertexPoint(ref vector, num, ref tattachPoint.bw); } else { if (!f_bTemp) { vector = tattachPoint.vOffsLocal; } vector += this.BindVert[num]; vector = transform.TransformPoint(vector); } vWorldPos = vector; if (f_bTemp) { qWorldRot = transform.rotation * tattachPoint.qSrc; vScaleRate = Vector3.one; } else { qWorldRot = transform.rotation * tattachPoint.qNow; vScaleRate = tattachPoint.vScaleRate; } return true; } public bool ResetAttachPoint(string apname) { if (!this.dicAttachPoint.ContainsKey(apname)) { Debug.LogError("アタッチポイント " + apname + " はありません。"); return false; } TAttachPoint tattachPoint = this.dicAttachPoint[apname]; tattachPoint.vidx = tattachPoint.srcvidx; tattachPoint.vOffsLocal = Vector3.zero; tattachPoint.qNow = tattachPoint.qSrc; tattachPoint.vScaleRate = Vector3.one; tattachPoint.bw = this.m_bws[tattachPoint.vidx]; this.bodyskin.body.maid.ClearAttachPointPos(this.bodyskin.m_ParentMPN, this.bodyskin.SlotId, apname); return true; } public void ReclucPointWorldAndScreen(Camera cam = null) { bool flag = cam != null; for (int i = 0; i < this.VCount; i++) { BoneWeight boneWeight = this.m_bws[i]; Vector3 zero = Vector3.zero; this.CalcVertexPoint(ref zero, i, ref boneWeight); this.WorldV[i] = zero; if (flag) { this.ScrnV[i] = cam.WorldToScreenPoint(zero); } } } private void CalcVertexPoint(ref Vector3 vPosLocalToWorld, int nVtx, ref BoneWeight bw) { vPosLocalToWorld += this.m_bones[bw.boneIndex0].transform.TransformPoint(this.m_bindposes[bw.boneIndex0].MultiplyPoint(this.m_vTmpVert[nVtx])) * bw.weight0; if (bw.weight1 != 0f) { vPosLocalToWorld += this.m_bones[bw.boneIndex1].TransformPoint(this.m_bindposes[bw.boneIndex1].MultiplyPoint(this.m_vTmpVert[nVtx])) * bw.weight1; } if (bw.weight2 != 0f) { vPosLocalToWorld += this.m_bones[bw.boneIndex2].TransformPoint(this.m_bindposes[bw.boneIndex2].MultiplyPoint(this.m_vTmpVert[nVtx])) * bw.weight2; } if (bw.weight3 != 0f) { vPosLocalToWorld += this.m_bones[bw.boneIndex3].TransformPoint(this.m_bindposes[bw.boneIndex3].MultiplyPoint(this.m_vTmpVert[nVtx])) * bw.weight3; } } private Vector3 CalcVertexPointWorldToLocal(Vector3 vWorld, int nVtx, ref BoneWeight bw) { Vector3 vector = Vector3.zero; vector += this.m_bones[bw.boneIndex0].transform.InverseTransformPoint(vWorld) * bw.weight0; if (bw.weight1 != 0f) { vector += this.m_bones[bw.boneIndex1].InverseTransformPoint(vWorld) * bw.weight1; } if (bw.weight2 != 0f) { vector += this.m_bones[bw.boneIndex2].InverseTransformPoint(vWorld) * bw.weight2; } if (bw.weight3 != 0f) { vector += this.m_bones[bw.boneIndex3].InverseTransformPoint(vWorld) * bw.weight3; } return vector; } private Vector3 CalcVertexPointLocalToWorld(Vector3 vLocal, int nVtx, ref BoneWeight bw) { Vector3 vector = Vector3.zero; vector += this.m_bones[bw.boneIndex0].transform.TransformPoint(vLocal) * bw.weight0; if (bw.weight1 != 0f) { vector += this.m_bones[bw.boneIndex1].TransformPoint(vLocal) * bw.weight1; } if (bw.weight2 != 0f) { vector += this.m_bones[bw.boneIndex2].TransformPoint(vLocal) * bw.weight2; } if (bw.weight3 != 0f) { vector += this.m_bones[bw.boneIndex3].TransformPoint(vLocal) * bw.weight3; } return vector; } public int VHitChk(Camera cam, Vector3 msv, out Vector3 vHitWorld) { if (this.m_nOriTri == null || this.m_nOriTri.Length == 0) { this.m_nOriTri = this.m_mesh.triangles; this.TriCount = this.m_nOriTri.Length; } int num = -1; float num2 = float.PositiveInfinity; for (int i = 0; i < this.TriCount; i += 3) { int num3 = this.m_nOriTri[i]; int num4 = this.m_nOriTri[i + 1]; int num5 = this.m_nOriTri[i + 2]; Vector3 vector = this.ScrnV[num3]; Vector3 vector2 = this.ScrnV[num4]; Vector3 vector3 = this.ScrnV[num5]; float z = vector.z; vector.z = 0f; float z2 = vector2.z; vector2.z = 0f; float z3 = vector3.z; vector3.z = 0f; if (Vector3.Cross(vector2 - vector, vector3 - vector2).z <= 0f) { if ((double)Vector3.Cross(msv - vector, vector2 - vector).z >= 0.0 && (double)Vector3.Cross(msv - vector2, vector3 - vector2).z >= 0.0 && (double)Vector3.Cross(msv - vector3, vector - vector3).z >= 0.0) { if (z < num2) { num2 = z; num = i; } } } } if (num != -1) { Debug.DrawLine(this.WorldV[this.m_nOriTri[num]], this.WorldV[this.m_nOriTri[num + 1]], Color.cyan); Debug.DrawLine(this.WorldV[this.m_nOriTri[num + 1]], this.WorldV[this.m_nOriTri[num + 2]], Color.cyan); Debug.DrawLine(this.WorldV[this.m_nOriTri[num]], this.WorldV[this.m_nOriTri[num + 2]], Color.cyan); } vHitWorld = Vector3.zero; if (num != -1) { float d = 0f; Plane plane = new Plane(this.WorldV[this.m_nOriTri[num]], this.WorldV[this.m_nOriTri[num + 1]], this.WorldV[this.m_nOriTri[num + 2]]); Ray ray = cam.ScreenPointToRay(msv); if (plane.Raycast(ray, out d)) { vHitWorld = ray.origin + ray.direction * d; } else { Debug.LogWarning("当たって居ない"); } } return num; } public void Test(Vector3 vc) { float num = (vc - this.DefVert[0]).sqrMagnitude; int num2 = 0; for (int i = 0; i < this.m_vOriVert.Length; i++) { float sqrMagnitude = (vc - this.DefVert[i]).sqrMagnitude; if (num > sqrMagnitude) { num = sqrMagnitude; num2 = i; } } this.attach_FaceHana = num2; } public float ChkHit(Camera cam) { Ray ray = cam.ScreenPointToRay(Input.mousePosition); float num = 0f; float num2 = 0f; int num3 = -1; float num4 = 0f; for (int i = 0; i < this.TriCount / 3; i++) { float num5 = this.TriangleIntersect(ray, i); if (num5 > 0f && (num4 > num5 || num4 == 0f)) { num3 = i; num4 = num5; this.vHitPos = ray.origin + ray.direction * num5; num = this.HitUV.x; num2 = this.HitUV.y; } } this.HitAtr = 0; if (num3 >= 0) { Vector2[] uv = this.m_mesh.uv; float d = 1f - num - num2; Vector2 vector = uv[this.m_nOriTri[num3 * 3]] * d; vector += uv[this.m_nOriTri[num3 * 3 + 1]] * num; vector += uv[this.m_nOriTri[num3 * 3 + 2]] * num2; this.HitTextureUV = vector; this.HitAtr = (this.m_AtrVert[this.m_nOriTri[num3 * 3]] | this.m_AtrVert[this.m_nOriTri[num3 * 3 + 1]] | this.m_AtrVert[this.m_nOriTri[num3 * 3 + 2]]); } return num4; } private float TriangleIntersect(Ray ray, int triidx) { Vector3 origin = ray.origin; Vector3 normalized = ray.direction.normalized; Vector3 b = this.WorldV[this.m_nOriTri[triidx * 3]]; Vector3 a = this.WorldV[this.m_nOriTri[triidx * 3 + 1]]; Vector3 a2 = this.WorldV[this.m_nOriTri[triidx * 3 + 2]]; Vector3 lhs = a - b; Vector3 lhs2 = a2 - b; Vector3 rhs = Vector3.Cross(lhs2, normalized); float num = Vector3.Dot(lhs, rhs); if (num >= -1E-08f) { return 0f; } Vector3 vector = origin - b; float num2 = Vector3.Dot(vector, rhs); if ((double)num2 > 0.0 || num2 < num) { return 0f; } Vector3 rhs2 = Vector3.Cross(lhs, vector); float num3 = Vector3.Dot(normalized, rhs2); if ((double)num3 > 0.0 || num2 + num3 < num) { return 0f; } float num4 = 1f / num; float num5 = Vector3.Dot(lhs2, rhs2); num5 *= num4; num2 *= num4; num3 *= num4; this.HitUV.x = num2; this.HitUV.y = num3; return num5; } public void OnApplicationQuit() { Debug.LogError("TMorph OnApplicationQuit"); this.m_mesh.vertices = this.m_vOriVert; this.m_mesh.normals = this.m_vOriNorm; } public int MorphCount; public Hashtable hash; public Dictionary dicBlendSet = new Dictionary(); public Dictionary dicBlendAtr = new Dictionary(); public int IdxHOHO = -1; public int IdxHOHO2 = -1; public Dictionary dicAttachPoint = new Dictionary(); public int VCount; private int TriCount; private int BoneCount; private int m_nSubMeshCount; public Vector3[] BindVert; public Vector3[] ScrnV; public Vector3[] WorldV; public int[] BindBone; public Vector3[] DefVert; public Vector3[] m_vOriVert; public Vector3[] m_vOriNorm; public int[] m_nOriTri; public int[][] m_nSubMeshOriTri; private Vector3[] m_vTmpVert; private Vector3[] m_vTmpNorm; public int[][] m_nSubMeshTmpTri; private int[] m_AtrVert; public List BlendDatas; public int[] BlendDataIdx_EyeClose; public float m_fEyeCloseRate; public float EyeMabataki; public int m_BlendDataIdx_FaceShape = -1; public float m_fFaceShapeRate; public int BlendDataIdx_LipSyncTh; public int BlendDataIdx_LipSync_A; public int BlendDataIdx_LipSync_S; public int BlendDataIdx_LipSync_C; public int BlendDataIdx_LipSync_W; public int BlendDataIdx_LipSync_ToothOFF; public int BlendDataIdx_Tear1; public int BlendDataIdx_Tear2; public int BlendDataIdx_Tear3; private float m_LipSync1; private float m_LipSync2; private float m_LipSync3; public bool boLipSync; public bool boLookTooth; public bool boBallGAG; public bool boNoseFook; public int BlendDataIdx_NoseFook; public int BlendDataIdx_RegFat; public int BlendDataIdx_RegMeet; private SkinnedMeshRenderer smr_src; private Transform[] m_bones; private Transform tRoot; private Mesh m_mesh; private BoneWeight[] m_bws; private Matrix4x4[] m_bindposes; private float[] BlendValues; private float[] BlendValuesTemp; private float[] BlendValuesBackup; private float[] BlendValuesCHK; public float UruUruScaleX; public List BoneNames; public List BoneVisible; public TBodySkin bodyskin; public int attach_FaceHana; private string Category; private TBody.SlotID SlotId; private bool m_bIsBody; private bool m_bMorph; private static string[] AtrVertChk = new string[] { "Mune", "Hip" }; private bool m_bDut; public Vector3 vHitPos; public Vector2 HitTextureUV; public Vector2 HitUV; public int HitAtr; [Flags] public enum AddBlendType { None = 0, Cheek1 = 1, Cheek2 = 2, Cheek3 = 4, Blush = 8, Tear1 = 16, Tear2 = 32, Tear3 = 64, TearBig = 128, Yodare = 256, Shock = 512 } public class TempAttachPos { public int m_nVidx; public Vector3 m_vPos; public Vector3 m_vScale; public Quaternion m_qRot; } }