Ejemplo n.º 1
0
        /// <summary>
        /// クロスデータ作成
        /// </summary>
        void CreateClothdata(MagicaBoneSpring scr)
        {
            if (scr.MeshData == null)
            {
                return;
            }

            // クロスデータ共有データ作成(既存の場合は選択状態のみコピーする)
            string dataname = "BoneSpringData_" + scr.name;
            var    cloth    = ShareDataObject.CreateShareData <ClothData>(dataname);

            // セレクトデータはすべて「移動」で受け渡す
            List <int> selectList = new List <int>();

            for (int i = 0; i < scr.MeshData.VertexCount; i++)
            {
                selectList.Add(SelectionData.Move);
            }

            // クロスデータ作成
            cloth.CreateData(
                scr,
                scr.Params,
                scr.TeamData,
                scr.MeshData,
                scr,
                selectList
                );
            serializedObject.FindProperty("clothData").objectReferenceValue = cloth;

            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(cloth);
        }
Ejemplo n.º 2
0
        //=========================================================================================
        /// <summary>
        /// クロス初期化
        /// </summary>
        protected override void ClothInit()
        {
            // 中央トランスフォームに移動パーティクルを1つ設定する(これが揺れる)
            // クロスデータはこの場で作成する
            ClothData cdata = ShareDataObject.CreateShareData <ClothData>("ClothData_work");

            cdata.selectionData.Add(SelectionData.Move);
            cdata.vertexFlagLevelList.Add(0);
            cdata.vertexDepthList.Add(0);
            cdata.rootList.Add(0);
            cdata.useVertexList.Add(0);
            cdata.initScale       = SpringData.initScale;
            cdata.SaveDataHash    = 1;
            cdata.SaveDataVersion = cdata.GetVersion();
            ClothData             = cdata;

            // エラーが出ないように
            clothDataHash    = cdata.SaveDataHash;
            clothDataVersion = cdata.SaveDataVersion;

            // クロス初期化
            base.ClothInit();

            // スプリングではClampPositonの速度制限は無視する
            MagicaPhysicsManager.Instance.Team.SetFlag(TeamId, PhysicsManagerTeamData.Flag_IgnoreClampPositionVelocity, true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 近接ラインの接続
        /// </summary>
        /// <param name="lineSet"></param>
        /// <param name="wposList"></param>
        /// <param name="mdata"></param>
        //void CreateNearLine(BoneCloth scr, HashSet<uint> lineSet, List<Vector3> wposList, MeshData mdata)
        //{
        //    for (int i = 0; i < (mdata.VertexCount - 1); i++)
        //    {
        //        for (int j = i + 1; j < mdata.VertexCount; j++)
        //        {
        //            float dist = Vector3.Distance(wposList[i], wposList[j]);
        //            if (dist <= scr.ClothTarget.ConnectionDistance)
        //            {
        //                // 接続
        //                uint pair = DataUtility.PackPair(i, j);
        //                lineSet.Add(pair);
        //            }
        //        }
        //    }
        //}

        /// <summary>
        /// クロスデータ作成
        /// </summary>
        void CreateClothdata(MagicaBoneCloth scr)
        {
            if (scr.MeshData == null)
            {
                return;
            }

            // クロスデータ共有データ作成(既存の場合は選択状態のみコピーする)
            string dataname = "BoneClothData_" + scr.name;
            var    cloth    = ShareDataObject.CreateShareData <ClothData>(dataname);

            // クロスデータ作成
            cloth.CreateData(
                scr,
                scr.Params,
                scr.TeamData,
                scr.MeshData,
                scr,
                scr.ClothSelection.GetSelectionData(scr.MeshData, null)
                );
            serializedObject.FindProperty("clothData").objectReferenceValue = cloth;

            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(cloth);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 新規選択クラスを作成して返す
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        protected SelectionData CreateSelection(MonoBehaviour obj, string property)
        {
            string dataname  = "SelectionData_" + obj.name;
            var    selection = ShareDataObject.CreateShareData <SelectionData>(dataname);

            return(selection);
        }
Ejemplo n.º 5
0
        //=========================================================================================
        /// <summary>
        /// データ作成
        /// </summary>
        void CreateData()
        {
            MagicaMeshCloth scr = target as MagicaMeshCloth;

            Debug.Log("Started creating. [" + scr.name + "]");

            // 共有選択データが存在しない場合は作成する
            if (scr.ClothSelection == null)
            {
                InitSelectorData();
            }

            // チームハッシュを設定
            scr.TeamData.ValidateColliderList();

            // クロスデータ共有データ作成
            string dataname = "MeshClothData_" + scr.name;
            var    cloth    = ShareDataObject.CreateShareData <ClothData>(dataname);

            // クロスデータ用にセレクションデータを拡張する
            // (1)無効頂点の隣接が移動/固定頂点なら拡張に変更する
            // (2)移動/固定頂点に影響する子頂点に接続する無効頂点は拡張に変更する
            var selection = scr.Deformer.MeshData.ExtendSelection(
                scr.ClothSelection.GetSelectionData(scr.Deformer.MeshData, scr.Deformer.GetRenderDeformerMeshList()),
                true,
                true
                );

            // クロスデータ作成
            cloth.CreateData(
                scr,
                scr.Params,
                scr.TeamData,
                scr.Deformer.MeshData,
                scr.Deformer,
                selection
                );

            // クロスデータを設定
            var cdata = serializedObject.FindProperty("clothData");

            cdata.objectReferenceValue = cloth;
            serializedObject.ApplyModifiedProperties();

            // 検証
            scr.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(cloth);

            if (scr.VerifyData() == Define.Error.None)
            {
                Debug.Log("Creation completed. [" + scr.name + "]");
            }
            else
            {
                Debug.LogError("Creation failed.");
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// sourceの共有データを複製して再セットする
        /// 再セットした共有データを返す
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public override ShareDataObject DuplicateShareDataObject(ShareDataObject source)
        {
            if (Deformer.MeshData == source)
            {
                //Deformer.MeshData = Instantiate(Deformer.MeshData);
                Deformer.MeshData = ShareDataObject.Clone(Deformer.MeshData);
                return(Deformer.MeshData);
            }

            return(null);
        }
        //=========================================================================================
        /// <summary>
        /// データ作成
        /// </summary>
        void CreateData()
        {
            MagicaMeshSpring scr = target as MagicaMeshSpring;

            Debug.Log("Started creating. [" + scr.name + "]");

            // センタートランスフォーム
            if (scr.CenterTransform == null)
            {
                serializedObject.FindProperty("centerTransform").objectReferenceValue = scr.transform;
            }

            // デフォーマーリスト整理
            //scr.VerifyDeformer();

            // 共有データオブジェクト作成
            SpringData sdata = ShareDataObject.CreateShareData <SpringData>("SpringData_" + scr.name);

            serializedObject.ApplyModifiedProperties();
            CreateClothData(scr, sdata, scr.GetDeformer(0));

            // データ検証
            sdata.CreateVerifyData();

            // 新しいデータを設定
            serializedObject.FindProperty("springData").objectReferenceValue = sdata;
            serializedObject.ApplyModifiedProperties();

            // 仮想デフォーマーのハッシュを設定
            //var property = serializedObject.FindProperty("virtualDeformerHash");
            //property.intValue = scr.VirtualDeformerHash;
            //serializedObject.ApplyModifiedProperties();

            // データ検証
            scr.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(sdata);

            if (scr.VerifyData() == Define.Error.None)
            {
                Debug.Log("Creation completed. [" + scr.name + "]");
            }
            else
            {
                Debug.LogError("Creation failed.");
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// sourceの共有データを複製して再セットする
        /// 再セットした共有データを返す
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public override ShareDataObject DuplicateShareDataObject(ShareDataObject source)
        {
            var sdata = base.DuplicateShareDataObject(source);

            if (sdata != null)
            {
                return(sdata);
            }

            if (MeshData == source)
            {
                //meshData = Instantiate(MeshData);
                meshData = ShareDataObject.Clone(MeshData);
                return(meshData);
            }

            return(null);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// sourceの共有データを複製して再セットする
        /// 再セットした共有データを返す
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public override ShareDataObject DuplicateShareDataObject(ShareDataObject source)
        {
            if (ClothData == source)
            {
                //clothData = Instantiate(ClothData);
                clothData = ShareDataObject.Clone(ClothData);
                return(clothData);
            }

            if (ClothSelection == source)
            {
                //clothSelection = Instantiate(ClothSelection);
                clothSelection = ShareDataObject.Clone(ClothSelection);
                return(clothSelection);
            }

            return(null);
        }
Ejemplo n.º 10
0
        //=========================================================================================
        /// <summary>
        /// 事前データ作成(エディット時のみ)
        /// ※RenderDeformerはマルチ選択+コンポーネントアタッチで自動生成する必要があるのでこちらに配置する
        /// </summary>
        public void CreateData()
        {
            Debug.Log("Started creating. [" + this.name + "]");

            var serializedObject = new SerializedObject(this);

            // ターゲットオブジェクト
            serializedObject.FindProperty("deformer.targetObject").objectReferenceValue = gameObject;
            serializedObject.FindProperty("deformer.dataHash").intValue = 0;

            // 共有データ作成
            var meshData = ShareDataObject.CreateShareData <MeshData>("RenderMeshData_" + this.name);

            // renderer
            var ren = GetComponent <Renderer>();

            if (ren == null)
            {
                Debug.LogError("Creation failed. Renderer not found.");
                return;
            }

            Mesh sharedMesh = null;

            if (ren is SkinnedMeshRenderer)
            {
                meshData.isSkinning = true;
                var sren = ren as SkinnedMeshRenderer;
                sharedMesh = sren.sharedMesh;
            }
            else
            {
                meshData.isSkinning = false;
                var meshFilter = ren.GetComponent <MeshFilter>();
                if (meshFilter == null)
                {
                    Debug.LogError("Creation failed. MeshFilter not found.");
                    return;
                }
                sharedMesh = meshFilter.sharedMesh;
            }

            // 頂点
            meshData.vertexCount = sharedMesh.vertexCount;

            // 頂点ハッシュ
            var          vlist          = sharedMesh.vertices;
            List <ulong> vertexHashList = new List <ulong>();

            for (int i = 0; i < vlist.Length; i++)
            {
                var vhash = DataHashExtensions.GetVectorDataHash(vlist[i]);
                //Debug.Log("[" + i + "] (" + (vlist[i] * 1000) + ") :" + vhash);
                vertexHashList.Add(vhash);
            }
            meshData.vertexHashList = vertexHashList.ToArray();

            // トライアングル
            meshData.triangleCount = sharedMesh.triangles.Length / 3;

            // レンダーデフォーマーのメッシュデータにはローカル座標、法線、接線、UV、トライアングルリストは保存しない
            // 不要なため

            // ボーン
            int boneCount = meshData.isSkinning ? sharedMesh.bindposes.Length : 1;

            meshData.boneCount = boneCount;

            // メッシュデータの検証とハッシュ
            meshData.CreateVerifyData();

            serializedObject.FindProperty("deformer.sharedMesh").objectReferenceValue = sharedMesh;
            serializedObject.FindProperty("deformer.meshData").objectReferenceValue   = meshData;
            serializedObject.FindProperty("deformer.meshOptimize").intValue           = EditUtility.GetOptimizeMesh(sharedMesh);
            serializedObject.ApplyModifiedProperties();

            // デフォーマーデータの検証とハッシュ
            Deformer.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            // コアコンポーネントの検証とハッシュ
            CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(meshData);

            // 変更後数
            Debug.Log("Creation completed. [" + this.name + "]");
        }
 /// <summary>
 /// sourceの共有データを複製して再セットする
 /// 再セットした共有データを返す
 /// </summary>
 /// <param name="source"></param>
 /// <returns></returns>
 public override ShareDataObject DuplicateShareDataObject(ShareDataObject source)
 {
     return(null);
 }
Ejemplo n.º 12
0
        /// <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>
        void CreateMeshData(MagicaBoneCloth scr)
        {
            // 共有データオブジェクト作成
            string   dataname = "BoneClothMeshData_" + scr.name;
            MeshData mdata    = ShareDataObject.CreateShareData <MeshData>(dataname);

            // トランスフォームリスト作成
            var transformList = scr.GetTransformList();

            if (transformList.Count == 0)
            {
                return;
            }

            // 頂点作成
            int            vcnt     = transformList.Count;
            List <Vector3> wposList = new List <Vector3>();
            List <Vector3> wnorList = new List <Vector3>();
            List <Vector4> wtanList = new List <Vector4>();
            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);
                wnorList.Add(t.forward);
                wtanList.Add(t.up);
                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;

            // デプスリスト作成
            var        sel       = scr.ClothSelection.GetSelectionData(null, null);
            List <int> depthList = new List <int>();

            for (int i = 0; i < transformList.Count; i++)
            {
                int depth = 0;
                var t     = transformList[i];

                while (t && transformList.Contains(t))
                {
                    int index = transformList.IndexOf(t);
                    if (sel[index] != SelectionData.Move)
                    {
                        break;
                    }

                    depth++;
                    t = t.parent;
                }

                depthList.Add(depth);
                //Debug.Log($"[{transformList[i].name}] depth:{depth}");
            }


            // 構造ライン
            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);
                }
            }

            // グリッドによるトライアングル
            List <int> triangleList = new List <int>();

            if (scr.ClothTarget.Connection == BoneClothTarget.ConnectionMode.Mesh)
            {
                HashSet <uint> triangleLineSet = new HashSet <uint>(lineSet);

                // 周りのボーンを調べ一定範囲内のボーンを接続する
                for (int i = 0; i < transformList.Count; i++)
                {
                    //if (sel[i] != SelectionData.Move)
                    //    continue;

                    var   t       = transformList[i];
                    int   depth   = depthList[i];
                    float mindist = 10000.0f;

                    List <int>   linkList = new List <int>();
                    List <float> distList = new List <float>();

                    for (int j = 0; j < transformList.Count; j++)
                    {
                        if (i == j || depthList[j] != depth)
                        {
                            continue;
                        }

                        linkList.Add(j);
                        var dist = Vector3.Distance(t.position, transformList[j].position);
                        distList.Add(dist);
                        mindist = Mathf.Min(mindist, dist);
                    }

                    // 最短距離より少し長めの範囲の頂点以外は削除する
                    HashSet <int> removeSet = new HashSet <int>();
                    mindist *= 1.5f;
                    for (int j = 0; j < linkList.Count; j++)
                    {
                        if (distList[j] > mindist)
                        {
                            removeSet.Add(j);
                        }
                    }

#if true
                    // 方向が一定以内ならば最も近い接続以外を削除する
                    for (int j = 0; j < linkList.Count - 1; j++)
                    {
                        for (int k = j + 1; k < linkList.Count; k++)
                        {
                            if (removeSet.Contains(j))
                            {
                                continue;
                            }
                            if (removeSet.Contains(k))
                            {
                                continue;
                            }

                            int index0 = linkList[j];
                            int index1 = linkList[k];

                            var ang = Vector3.Angle(transformList[index0].position - t.position, transformList[index1].position - t.position);
                            if (ang <= 45.0f)
                            {
                                removeSet.Add(distList[j] < distList[k] ? k : j);
                            }
                        }
                    }
#endif
                    // 登録
                    for (int j = 0; j < linkList.Count; j++)
                    {
                        if (removeSet.Contains(j))
                        {
                            continue;
                        }
                        // 接続する
                        uint pair = DataUtility.PackPair(i, linkList[j]);
                        triangleLineSet.Add(pair);
                    }
                }

                // 一旦各頂点の接続頂点リストを取得
                var vlink = MeshUtility.GetVertexLinkList(mdata.vertexCount, triangleLineSet);

                // トライアングル情報作成
                HashSet <ulong> registTriangleSet = new HashSet <ulong>();
                for (int i = 0; i < vlink.Count; i++)
                {
                    var linkset = vlink[i];
                    var t       = transformList[i];
                    var move    = sel[i] == SelectionData.Move;

                    foreach (var j in linkset)
                    {
                        var t2    = transformList[j];
                        var v     = (t2.position - t.position).normalized;
                        var move2 = sel[j] == SelectionData.Move;

                        foreach (var k in linkset)
                        {
                            if (j == k)
                            {
                                continue;
                            }

                            // j-kのエッジがtriangleLineSetに含まれていない場合は無効
                            //if (triangleLineSet.Contains(DataUtility.PackPair(j, k)) == false)
                            //    continue;

                            var t3    = transformList[k];
                            var v2    = (t3.position - t.position).normalized;
                            var move3 = sel[k] == SelectionData.Move;

                            // すべて固定頂点なら無効
                            if (move == false && move2 == false && move3 == false)
                            {
                                continue;
                            }

                            // 面積が0のトライアングルは除外する
                            var n    = Vector3.Cross(t2.position - t.position, t3.position - t.position);
                            var clen = n.magnitude;
                            if (clen < 1e-06f)
                            {
                                //Debug.Log($"clen == 0 ({i},{j},{k})");
                                continue;
                            }

                            var ang = Vector3.Angle(v, v2); // deg
                            if (ang <= 100)
                            {
                                // i - j - k をトライアングルとして登録する
                                var thash = DataUtility.PackTriple(i, j, k);
                                if (registTriangleSet.Contains(thash) == false)
                                {
                                    triangleList.Add(i);
                                    triangleList.Add(j);
                                    triangleList.Add(k);
                                    registTriangleSet.Add(thash);
                                }
                            }
                        }
                    }
                }
            }

            // トライアングルの法線を揃える
            HashSet <ulong> triangleSet = new HashSet <ulong>();
            if (triangleList.Count > 0)
            {
                // リダクションメッシュを作成する
                // ただ現在は面法線を揃える用途にしか使用しない
                var reductionMesh = new MagicaReductionMesh.ReductionMesh();
                reductionMesh.WeightMode = MagicaReductionMesh.ReductionMesh.ReductionWeightMode.Distance;
                reductionMesh.MeshData.MaxWeightCount   = 1;
                reductionMesh.MeshData.WeightPow        = 1;
                reductionMesh.MeshData.SameSurfaceAngle = scr.ClothTarget.SameSurfaceAngle; // 80?
                reductionMesh.AddMesh(myt, wposList, wnorList, wtanList, null, triangleList);

                // リダクション(面法線を整えるだけでリダクションは行わない)
                reductionMesh.Reduction(0.0f, 0.0f, 0.0f, false);

                // 最終メッシュデータ取得
                var final = reductionMesh.GetFinalData(myt);
                Debug.Assert(vcnt == final.VertexCount);

                // トライアングルデータ取得
                triangleList = final.triangles;
            }

            // 近接ライン接続
            //if (scr.ClothTarget.LineConnection)
            //{
            //    CreateNearLine(scr, lineSet, wposList, mdata);
            //}

#if false
            // トライアングル接続されているエッジはラインセットから削除する
            for (int i = 0; i < triangleList.Count / 3; i++)
            {
                int v0, v1, v2;
                int index = i * 3;
                v0 = triangleList[index];
                v1 = triangleList[index + 1];
                v2 = triangleList[index + 2];

                var pair0 = DataUtility.PackPair(v0, v1);
                var pair1 = DataUtility.PackPair(v1, v2);
                var pair2 = DataUtility.PackPair(v2, v0);

                lineSet.Remove(pair0);
                lineSet.Remove(pair1);
                lineSet.Remove(pair2);
            }
#endif

            // todo:test
            //lineSet.Clear();

            // ライン格納
            if (lineSet.Count > 0)
            {
                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;
            }

            // トライアングル格納
            //if (triangleSet.Count > 0)
            //{
            //    List<int> triangleList = new List<int>();
            //    foreach (var tpack in triangleSet)
            //    {
            //        int v0, v1, v2;
            //        DataUtility.UnpackTriple(tpack, out v0, out v1, out v2);
            //        triangleList.Add(v0);
            //        triangleList.Add(v1);
            //        triangleList.Add(v2);
            //    }
            //    mdata.triangleCount = triangleSet.Count;
            //    mdata.triangleList = triangleList.ToArray();
            //}
            if (triangleList.Count > 0)
            {
                mdata.triangleCount = triangleList.Count / 3;
                mdata.triangleList  = triangleList.ToArray();
            }

            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);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// sourceの共有データを複製して再セットする
 /// 再セットした共有データを返す
 /// </summary>
 /// <param name="source"></param>
 /// <returns></returns>
 public abstract ShareDataObject DuplicateShareDataObject(ShareDataObject source);
Ejemplo n.º 15
0
        /// <summary>
        /// MagicaClothの共有データをサブアセットとしてプレハブに保存する
        /// またすでに不要なサブアセットは削除する
        /// </summary>
        /// <param name="prefab"></param>
        /// <param name="target"></param>
        /// <param name="prefabPath"></param>
        static void PrefabUpdate(GameObject prefab, GameObject target, string prefabPath)
        {
            //Debug.Log("PrefabUpdate()");
            //Debug.Log("prefab name:" + prefab.name);
            //Debug.Log("prefab id:" + prefab.GetInstanceID());
            //Debug.Log("target name:" + target.name);
            //Debug.Log("target id:" + target.GetInstanceID());
            //Debug.Log("prefab path:" + prefabPath);
            //Debug.Log("IsPersistent:" + EditorUtility.IsPersistent(prefab));
            //Debug.Log("AssetDatabase.Contains:" + AssetDatabase.Contains(prefab));
            //Debug.Log("IsPartOfModelPrefab:" + PrefabUtility.IsPartOfModelPrefab(prefab));
            //Debug.Log("IsPartOfPrefabThatCanBeAppliedTo:" + PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(prefab));
            //Debug.Log("IsPartOfImmutablePrefab:" + PrefabUtility.IsPartOfImmutablePrefab(prefab));


            // 編集不可のプレハブならば保存できないため処理を行わない
            if (PrefabUtility.IsPartOfImmutablePrefab(prefab))
            {
                return;
            }

            AssetDatabase.StartAssetEditing();

            // 不要な共有データを削除するためのリスト
            bool change = false;
            List <ShareDataObject> removeDatas = new List <ShareDataObject>();

            // 現在アセットとして保存されているすべてのShareDataObjectサブアセットを削除対象としてリスト化する
            UnityEngine.Object[] subassets = AssetDatabase.LoadAllAssetRepresentationsAtPath(prefabPath);
            if (subassets != null)
            {
                foreach (var obj in subassets)
                {
                    // ShareDataObjectのみ
                    ShareDataObject sdata = obj as ShareDataObject;
                    if (sdata)
                    {
                        //Debug.Log("sub asset:" + obj.name + " type:" + obj + " test:" + AssetDatabase.IsSubAsset(sdata));

                        // 削除対象として一旦追加
                        removeDatas.Add(sdata);
                    }
                }
            }

            // プレハブ元の共有オブジェクトをサブアセットとして保存する
            List <ShareDataObject> saveDatas = new List <ShareDataObject>();
            var shareDataInterfaces          = target.GetComponentsInChildren <IShareDataObject>(true);

            if (shareDataInterfaces != null)
            {
                foreach (var sdataInterface in shareDataInterfaces)
                {
                    List <ShareDataObject> shareDatas = sdataInterface.GetAllShareDataObject();
                    if (shareDatas != null)
                    {
                        foreach (var sdata in shareDatas)
                        {
                            if (sdata)
                            {
                                //Debug.Log("share data->" + sdata.name + " prefab?:" + AssetDatabase.Contains(sdata));
                                //Debug.Log("share data path:" + AssetDatabase.GetAssetPath(sdata));

                                if (AssetDatabase.Contains(sdata) == false)
                                {
                                    // サブアセットとして共有データを追加
                                    //Debug.Log("save sub asset:" + sdata.name);
                                    AssetDatabase.AddObjectToAsset(sdata, prefab);
                                    change = true;
                                }
                                else if (prefabPath != AssetDatabase.GetAssetPath(sdata))
                                {
                                    // 保存先プレハブが変更されている
                                    //Debug.Log("Change prefab!!");

                                    // 共有データのクローンを作成(別データとする)
                                    var newdata = sdataInterface.DuplicateShareDataObject(sdata);
                                    if (newdata != null)
                                    {
                                        //Debug.Log("save new data! ->" + newdata);
                                        AssetDatabase.AddObjectToAsset(newdata, prefab);
                                        change = true;
                                    }
                                }

                                removeDatas.Remove(sdata);
                            }
                        }
                    }
                }
            }

            // 不要な共有データは削除する
            foreach (var sdata in removeDatas)
            {
                //Debug.Log("Remove sub asset:" + sdata.name);
                UnityEngine.Object.DestroyImmediate(sdata, true);
                change = true;
            }

            AssetDatabase.StopAssetEditing();

            // 変更を全体に反映
            if (change)
            {
                //Debug.Log("save!");

                // どうもこの手順を踏まないと保存した共有データが正しくアタッチされない
                if (PrefabStageUtility.GetCurrentPrefabStage() != null)
                {
                    PrefabUtility.SaveAsPrefabAsset(target, prefabPath);
                }
                else
                {
                    PrefabUtility.SaveAsPrefabAssetAndConnect(target, prefabPath, InteractionMode.AutomatedAction);
                }
            }
        }
        static void SavePrefab(GameObject instance, string prefabPath, string savePrefabPath, bool isVariant, bool forceCopy, Mode mode)
        {
            //Debug.Log($"SavePrefab instance:{instance.name} forceCopy:{forceCopy} isVariant:{isVariant}\npath:{prefabPath}\nsavePath:{savePrefabPath} ");

            // 保存先プレハブアセット
            var savePrefab = AssetDatabase.LoadAssetAtPath <GameObject>(savePrefabPath);

            // 編集不可のプレハブならば保存できないため処理を行わない
            if (PrefabUtility.IsPartOfImmutablePrefab(savePrefab))
            {
                //Debug.Log("Skip3");
                return;
            }

            AssetDatabase.StartAssetEditing();

            // 不要な共有データを削除するためのリスト
            bool change = false;
            List <ShareDataObject> removeDatas = new List <ShareDataObject>();

            // 現在アセットとして保存されているすべてのShareDataObjectサブアセットを削除対象としてリスト化する
            List <Object> subassets = new List <Object>(AssetDatabase.LoadAllAssetRepresentationsAtPath(savePrefabPath));

            if (subassets != null)
            {
                foreach (var obj in subassets)
                {
                    // ShareDataObjectのみ
                    ShareDataObject sdata = obj as ShareDataObject;
                    if (sdata && removeDatas.Contains(sdata) == false)
                    {
                        //Debug.Log("remove reserve sub asset:" + obj.name + " type:" + obj + " test:" + AssetDatabase.IsSubAsset(sdata));
                        // 削除対象として一旦追加
                        removeDatas.Add(sdata);
                    }
                }
            }

            // データコンポーネント収集
            var coreList = instance.GetComponentsInChildren <CoreComponent>(true);

            if (coreList != null)
            {
                foreach (var core in coreList)
                {
                    // 共有データ収集
                    var shareDataInterfaces = core.GetComponentsInChildren <IShareDataObject>(true);
                    if (shareDataInterfaces != null)
                    {
                        foreach (var sdataInterface in shareDataInterfaces)
                        {
                            List <ShareDataObject> shareDatas = sdataInterface.GetAllShareDataObject();
                            if (shareDatas != null)
                            {
                                foreach (var sdata in shareDatas)
                                {
                                    if (sdata)
                                    {
                                        //Debug.Log($"target shareData:{sdata.name}");

                                        if (removeDatas.Contains(sdata))
                                        {
                                            //Debug.Log($"Ignore:{sdata.name}");
                                            removeDatas.Remove(sdata);
                                        }
                                        else if (AssetDatabase.Contains(sdata))
                                        {
                                            // アセットのプレハブパスを取得
                                            var sdataPrefabPath = AssetDatabase.GetAssetPath(sdata);
                                            //Debug.Log($"sdataPrefabPath:{sdataPrefabPath}");

                                            if (forceCopy || prefabPath != savePrefabPath)
                                            {
                                                var newdata = sdataInterface.DuplicateShareDataObject(sdata);
                                                if (newdata != null)
                                                {
                                                    //Debug.Log($"+Duplicate sub asset:{newdata.name} -> [{savePrefab.name}]");
                                                    AssetDatabase.AddObjectToAsset(newdata, savePrefab);
                                                    change = true;
                                                }
                                            }
                                            else
                                            {
                                                removeDatas.Remove(sdata);
                                            }
                                        }
                                        else
                                        {
                                            //Debug.Log($"+Add sub asset:{sdata.name} -> [{savePrefab.name}]");
                                            AssetDatabase.AddObjectToAsset(sdata, savePrefab);
                                            change = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // 不要な共有データは削除する
            foreach (var sdata in removeDatas)
            {
                //Debug.Log($"-Remove sub asset:{sdata.name} path:{AssetDatabase.GetAssetPath(sdata)}");
                UnityEngine.Object.DestroyImmediate(sdata, true);
                change = true;
            }

            AssetDatabase.StopAssetEditing();

            // 変更を反映する
            if (change)
            {
                //Debug.Log("save!");

                // どうもこの手順を踏まないと保存した共有データが正しくアタッチされない
                if (mode == Mode.Saving)
                {
                    PrefabUtility.SaveAsPrefabAsset(instance, savePrefabPath);
                }
                else
                {
                    PrefabUtility.SaveAsPrefabAssetAndConnect(instance, savePrefabPath, InteractionMode.AutomatedAction);
                }
            }
        }
Ejemplo n.º 17
0
 //=========================================================================================
 /// <summary>
 /// コライダーリスト検証
 /// </summary>
 public void ValidateColliderList()
 {
     // コライダーのnullや重複を削除する
     ShareDataObject.RemoveNullAndDuplication(colliderList);
 }
Ejemplo n.º 18
0
        //=========================================================================================
        /// <summary>
        /// 事前データ作成
        /// </summary>
        /// <param name="scr"></param>
        private void CreateData(MagicaVirtualDeformer scr)
        {
            Debug.Log("Started creating. [" + scr.name + "]");

            // 子メッシュの検証
            if (VerifyChildData(scr.Deformer) == false)
            {
                // error
                Debug.LogError("Setup failed. Invalid RenderDeformer data.");
                return;
            }

            serializedObject.FindProperty("deformer.targetObject").objectReferenceValue = scr.gameObject;

            // 新規メッシュデータ
            var meshData = ShareDataObject.CreateShareData <MeshData>("VirtualMeshData_" + scr.name);

            // 設計時スケール
            meshData.baseScale = scr.transform.lossyScale;

            // 仮想メッシュ作成
            var reductionMesh = new MagicaReductionMesh.ReductionMesh();

            reductionMesh.WeightMode = MagicaReductionMesh.ReductionMesh.ReductionWeightMode.Average; // 平均法(v1.5.2)
            reductionMesh.MeshData.MaxWeightCount   = scr.Deformer.MaxWeightCount;
            reductionMesh.MeshData.WeightPow        = scr.Deformer.WeightPow;
            reductionMesh.MeshData.SameSurfaceAngle = scr.Deformer.SameSurfaceAngle;
            for (int i = 0; i < scr.Deformer.RenderDeformerCount; i++)
            {
                var deformer = scr.Deformer.GetRenderDeformer(i).Deformer;
                if (deformer != null)
                {
                    var sren = deformer.TargetObject.GetComponent <SkinnedMeshRenderer>();
                    List <Transform> boneList = new List <Transform>();
                    if (sren)
                    {
                        boneList = new List <Transform>(sren.bones);
                    }
                    else
                    {
                        boneList.Add(deformer.TargetObject.transform);
                    }
                    reductionMesh.AddMesh(
                        deformer.MeshData.isSkinning,
                        deformer.SharedMesh,
                        boneList,
                        deformer.SharedMesh.bindposes,
                        deformer.SharedMesh.boneWeights
                        );
                }
            }

            //reductionMesh.DebugData.DispMeshInfo("リダクション前");

            // リダクション
            reductionMesh.Reduction(
                scr.Deformer.MergeVertexDistance > 0.0f ? 0.0001f : 0.0f,
                scr.Deformer.MergeVertexDistance,
                scr.Deformer.MergeTriangleDistance,
                false
                );

            // (1)ゼロ距離リダクション
            //if (scr.Deformer.MergeVertexDistance > 0.0f)
            //    reductionMesh.ReductionZeroDistance();

            //// (2)頂点距離マージ
            //if (scr.Deformer.MergeVertexDistance > 0.0001f)
            //    reductionMesh.ReductionRadius(scr.Deformer.MergeVertexDistance);

            //// (3)トライアングル接続マージ
            //if (scr.Deformer.MergeTriangleDistance > 0.0f)
            //    reductionMesh.ReductionPolygonLink(scr.Deformer.MergeTriangleDistance);

            //// (4)未使用ボーンの削除
            //reductionMesh.ReductionBone();

            // (5)頂点の最大接続トライアングル数制限
            //reductionMesh.ReductionTriangleConnect(6);

            //reductionMesh.DebugData.DispMeshInfo("リダクション後");

            // 最終メッシュデータ取得
            var final = reductionMesh.GetFinalData(scr.gameObject.transform);

            // メッシュデータシリアライズ
            meshData.isSkinning  = final.IsSkinning;
            meshData.vertexCount = final.VertexCount;

            List <uint> vlist;
            List <MeshData.VertexWeight> wlist;

            CreateVertexWeightList(
                final.VertexCount, final.vertices, final.normals, final.tangents, final.boneWeights, final.bindPoses,
                out vlist, out wlist
                );
            meshData.vertexInfoList   = vlist.ToArray();
            meshData.vertexWeightList = wlist.ToArray();
            meshData.boneCount        = final.BoneCount;

            meshData.uvList        = final.uvs.ToArray();
            meshData.lineCount     = final.LineCount;
            meshData.lineList      = final.lines.ToArray();
            meshData.triangleCount = final.TriangleCount;
            meshData.triangleList  = final.triangles.ToArray();

            List <uint> vertexToTriangleInfoList = new List <uint>();

            for (int i = 0; i < final.VertexCount; i++)
            {
                int tcnt   = final.vertexToTriangleCountList[i];
                int tstart = final.vertexToTriangleStartList[i];
                vertexToTriangleInfoList.Add(DataUtility.Pack8_24(tcnt, tstart));
            }
            meshData.vertexToTriangleInfoList  = vertexToTriangleInfoList.ToArray();
            meshData.vertexToTriangleIndexList = final.vertexToTriangleIndexList.ToArray();

            // 子メッシュ情報
            for (int i = 0; i < final.MeshCount; i++)
            {
                var minfo     = final.meshList[i];
                var rdeformer = scr.Deformer.GetRenderDeformer(i).Deformer;
                var mdata     = new MeshData.ChildData();

                mdata.childDataHash = rdeformer.GetDataHash();
                mdata.vertexCount   = minfo.VertexCount;

                // 頂点ウエイト情報作成
                CreateVertexWeightList(
                    minfo.VertexCount, minfo.vertices, minfo.normals, minfo.tangents, minfo.boneWeights, final.vertexBindPoses,
                    out vlist, out wlist
                    );

                mdata.vertexInfoList   = vlist.ToArray();
                mdata.vertexWeightList = wlist.ToArray();

                mdata.parentIndexList = minfo.parents.ToArray();

                meshData.childDataList.Add(mdata);
            }

            // レイヤー情報
            //for (int i = 0; i < final.LayerCount; i++)
            //{
            //    var linfo = new MeshData.LayerInfo();
            //    linfo.triangleList = new List<int>(final.layerList[i].triangleList);
            //    meshData.layerInfoList.Add(linfo);
            //}

            // 検証
            meshData.CreateVerifyData();
            serializedObject.FindProperty("deformer.meshData").objectReferenceValue = meshData;

            // ボーン
            var property = serializedObject.FindProperty("deformer.boneList");

            property.arraySize = final.bones.Count;
            for (int i = 0; i < final.bones.Count; i++)
            {
                property.GetArrayElementAtIndex(i).objectReferenceValue = final.bones[i];
            }

            serializedObject.ApplyModifiedProperties();

            // デフォーマーデータの検証とハッシュ
            scr.Deformer.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            // コアコンポーネントの検証とハッシュ
            scr.CreateVerifyData();
            serializedObject.ApplyModifiedProperties();

            EditorUtility.SetDirty(meshData);

            Debug.Log("Setup completed. [" + scr.name + "]");
        }