/// <summary> /// メッシュデータ作成 /// </summary> void CreateMeshData(MagicaBoneCloth scr) { // 共有データオブジェクト作成 string dataname = "BoneClothMeshData_" + scr.name; MeshData mdata = ShareDataObject.CreateShareData <MeshData>(dataname); // トランスフォームリスト作成 var transformList = scr.GetTransformList(); if (transformList.Count == 0) { return; } // 頂点作成 List <Vector3> wposList = new List <Vector3>(); List <Vector3> lposList = new List <Vector3>(); List <Vector3> lnorList = new List <Vector3>(); List <Vector3> ltanList = new List <Vector3>(); Transform myt = scr.transform; for (int i = 0; i < transformList.Count; i++) { var t = transformList[i]; // 頂点追加 var pos = t.position; var lpos = myt.InverseTransformDirection(pos - myt.position); var lnor = myt.InverseTransformDirection(t.forward); var ltan = myt.InverseTransformDirection(t.up); wposList.Add(pos); lposList.Add(lpos); lnorList.Add(lnor); ltanList.Add(ltan); } var vertexInfoList = new List <uint>(); var vertexWeightList = new List <MeshData.VertexWeight>(); for (int i = 0; i < lposList.Count; i++) { // 1ウエイトで追加 uint vinfo = DataUtility.Pack4_28(1, i); vertexInfoList.Add(vinfo); var vw = new MeshData.VertexWeight(); vw.parentIndex = i; vw.weight = 1.0f; vw.localPos = lposList[i]; vw.localNor = lnorList[i]; vw.localTan = ltanList[i]; } mdata.vertexInfoList = vertexInfoList.ToArray(); mdata.vertexWeightList = vertexWeightList.ToArray(); mdata.vertexCount = lposList.Count; // ライン作成 HashSet <uint> lineSet = new HashSet <uint>(); // 構造ライン for (int i = 0; i < transformList.Count; i++) { var t = transformList[i]; var pt = t.parent; if (pt != null && transformList.Contains(pt)) { int v0 = i; int v1 = transformList.IndexOf(pt); uint pair = DataUtility.PackPair(v0, v1); lineSet.Add(pair); } } // 近接ライン接続 //if (scr.ClothTarget.LineConnection) //{ // CreateNearLine(scr, lineSet, wposList, mdata); //} // ライン格納 List <int> lineList = new List <int>(); foreach (var pair in lineSet) { int v0, v1; DataUtility.UnpackPair(pair, out v0, out v1); lineList.Add(v0); lineList.Add(v1); } mdata.lineList = lineList.ToArray(); mdata.lineCount = lineList.Count / 2; serializedObject.FindProperty("meshData").objectReferenceValue = mdata; serializedObject.ApplyModifiedProperties(); // 使用トランスフォームシリアライズ var property = serializedObject.FindProperty("useTransformList"); var propertyPos = serializedObject.FindProperty("useTransformPositionList"); var propertyRot = serializedObject.FindProperty("useTransformRotationList"); var propertyScl = serializedObject.FindProperty("useTransformScaleList"); property.arraySize = transformList.Count; propertyPos.arraySize = transformList.Count; propertyRot.arraySize = transformList.Count; propertyScl.arraySize = transformList.Count; for (int i = 0; i < transformList.Count; i++) { property.GetArrayElementAtIndex(i).objectReferenceValue = transformList[i]; propertyPos.GetArrayElementAtIndex(i).vector3Value = transformList[i].localPosition; propertyRot.GetArrayElementAtIndex(i).quaternionValue = transformList[i].localRotation; propertyScl.GetArrayElementAtIndex(i).vector3Value = transformList[i].localScale; } serializedObject.ApplyModifiedProperties(); // データ検証とハッシュ mdata.CreateVerifyData(); serializedObject.ApplyModifiedProperties(); EditorUtility.SetDirty(mdata); }
/// <summary> /// メッシュ頂点の選択データを設定する /// </summary> /// <param name="meshData"></param> /// <param name="selects"></param> public void SetSelectionData(MeshData meshData, List <int> selects, List <MeshData> childMeshDataList) { // 選択データ初期化 selectionList.Clear(); if (meshData != null && meshData.ChildCount > 0) { for (int i = 0; i < meshData.ChildCount; i++) { var dsel = new DeformerSelection(); int cvcnt = meshData.childDataList[i].VertexCount; for (int j = 0; j < cvcnt; j++) { dsel.selectData.Add(Invalid); dsel.vertexHashList.Add(0); // ハッシュ0=無効 } selectionList.Add(dsel); } } else { // そのまま var dsel = new DeformerSelection(); int cvcnt = selects.Count; for (int j = 0; j < cvcnt; j++) { dsel.selectData.Add(Invalid); dsel.vertexHashList.Add(0); // ハッシュ0=無効 } selectionList.Add(dsel); } // 選択データに追加 for (int i = 0; i < selects.Count; i++) { int data = selects[i]; if (meshData != null && meshData.ChildCount > 0) { // 親頂点に影響する子頂点情報 Dictionary <int, List <uint> > dict = meshData.GetVirtualToChildVertexDict(); // 親頂点に影響する子頂点に記録 if (dict.ContainsKey(i)) { foreach (var pack in dict[i]) { int cmindex = DataUtility.Unpack16Hi(pack); int cvindex = DataUtility.Unpack16Low(pack); selectionList[cmindex].selectData[cvindex] = data; // 頂点ハッシュも記録 if (cmindex < childMeshDataList.Count) { var cmdata = childMeshDataList[cmindex]; if (cmdata != null && cvindex < cmdata.VertexHashCount) { selectionList[cmindex].vertexHashList[cvindex] = cmdata.vertexHashList[cvindex]; } } } } } else { // そのまま selectionList[0].selectData[i] = data; } } // データハッシュ設定 CreateVerifyData(); }
/// <summary> /// メッシュデータから頂点/法線/接線をワールド座標変換して返す /// </summary> /// <param name="meshData"></param> /// <param name="boneList"></param> /// <param name="wposList"></param> /// <param name="wnorList"></param> /// <param name="wtanList"></param> /// <returns></returns> public static bool CalcMeshWorldPositionNormalTangent( MeshData meshData, List <Transform> boneList, out List <Vector3> wposList, out List <Vector3> wnorList, out List <Vector3> wtanList ) { wposList = new List <Vector3>(); wnorList = new List <Vector3>(); wtanList = new List <Vector3>(); if (meshData == null || boneList == null) { return(false); } if (meshData.isSkinning == false) { // 通常メッシュ Transform t = boneList[0]; for (int i = 0; i < meshData.VertexCount; i++) { // 頂点スキニング var vw = meshData.vertexWeightList[i]; Vector3 wpos = t.TransformPoint(vw.localPos); Vector3 wnor = t.TransformDirection(vw.localNor); Vector3 wtan = t.TransformDirection(vw.localTan); wposList.Add(wpos); wnorList.Add(wnor); wtanList.Add(wtan); } } else { // スキンメッシュ float[] weights = new float[4]; int[] boneIndexs = new int[4]; for (int i = 0; i < meshData.VertexCount; i++) { Vector3 wpos = Vector3.zero; Vector3 wnor = Vector3.zero; Vector3 wtan = Vector3.zero; // 頂点スキニング uint pack = meshData.vertexInfoList[i]; int wcnt = DataUtility.Unpack4_28Hi(pack); int sindex = DataUtility.Unpack4_28Low(pack); for (int j = 0; j < wcnt; j++) { var vw = meshData.vertexWeightList[sindex + j]; Transform t = boneList[vw.parentIndex]; wpos += t.TransformPoint(vw.localPos) * vw.weight; wnor += t.TransformDirection(vw.localNor) * vw.weight; wtan += t.TransformDirection(vw.localTan) * vw.weight; } wposList.Add(wpos); wnorList.Add(wnor); wtanList.Add(wtan); } } return(true); }