Esempio n. 1
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="target">カットターゲット</param>
 public CutterObject(CutterTarget target, bool needAnimation = false)
 {
     _target = target;
     _name   = target.Name;
     GetMeshInfo(target.GameObject, out _mesh, out _bindposes);
     CutterMesh = new CutterMesh(_mesh);
 }
Esempio n. 2
0
            public MeshCutData(CutterMesh victimMesh, CutterPlane blade)
            {
                VictimMesh = victimMesh;
                LeftSide.SetTargetMesh(victimMesh);
                RightSide.SetTargetMesh(victimMesh);

                Blade = blade;
            }
Esempio n. 3
0
        /// <summary>
        /// Cut the specified victim, blade_plane and capMaterial.
        /// (指定された「victim」をカットする。ブレード(平面)とマテリアルから切断を実行する)
        /// </summary>
        /// <param name="victim">Victim.</param>
        /// <param name="blade_plane">Blade plane.</param>
        public CutterMesh[] Cut(CutterObject victim, CutterPlane blade)
        {
            // 対象のメッシュを取得
            MeshCutData data = new MeshCutData(victim.CutterMesh, blade);

            // ここでの「3」はトライアングル
            bool[] sides = new bool[3];
            int[]  indices;
            int    p1, p2, p3;

            // go throught the submeshes
            // サブメッシュの数だけループ
            for (int sub = 0; sub < victim.SubMeshCount; sub++)
            {
                // サブメッシュのインデックス数を取得
                indices = victim.CutterMesh.GetIndices(sub);

                // List<List<int>>型のリスト。サブメッシュ一つ分のインデックスリスト
                data.LeftSide.SubIndices.Add(new List <int>());  // 左
                data.RightSide.SubIndices.Add(new List <int>()); // 右

                // サブメッシュのインデックス数分ループ
                for (int i = 0; i < indices.Length; i += 3)
                {
                    // p1 - p3のインデックスを取得。つまりトライアングル
                    p1 = indices[i + 0];
                    p2 = indices[i + 1];
                    p3 = indices[i + 2];

                    // それぞれ評価中のメッシュの頂点が、冒頭で定義された平面の左右どちらにあるかを評価。
                    // `GetSide` メソッドによりboolを得る。
                    sides[0] = blade.GetSide(data.VictimMesh.Vertices[p1]);
                    sides[1] = blade.GetSide(data.VictimMesh.Vertices[p2]);
                    sides[2] = blade.GetSide(data.VictimMesh.Vertices[p3]);

                    // whole triangle
                    // 頂点0と頂点1および頂点2がどちらも同じ側にある場合はカットしない
                    if (sides[0] == sides[1] && sides[0] == sides[2])
                    {
                        if (sides[0])
                        {   // left side
                            // GetSideメソッドでポジティブ(true)の場合は左側にあり
                            data.LeftSide.AddTriangle(p1, p2, p3, sub);
                        }
                        else
                        {
                            data.RightSide.AddTriangle(p1, p2, p3, sub);
                        }
                    }
                    else
                    {   // cut the triangle
                        // そうではなく、どちらかの点が平面の反対側にある場合はカットを実行する
                        CutFace(sub, sides, p1, p2, p3, data);
                    }
                }
            }

            // Check separating verticies.
            if (data.LeftSide.Vertices.Count == 0 || data.RightSide.Vertices.Count == 0)
            {
                Debug.Log("No need cutting, because all verticies are in one side.");
                return(null);
            }

            data.LeftSide.SubIndices.Add(new List <int>());
            data.RightSide.SubIndices.Add(new List <int>());

            // カット開始
            Capping(data);

            // 左側のメッシュを生成
            // MeshCutSideクラスのメンバから各値をコピー
            CutterMesh leftHalfMesh = new CutterMesh
            {
                Vertices    = data.LeftSide.Vertices.ToArray(),
                Triangles   = data.LeftSide.Triangles.ToArray(),
                Normals     = data.LeftSide.Normals.ToArray(),
                UVs         = data.LeftSide.UVs.ToArray(),
                BoneWeights = data.LeftSide.BoneWeights.ToArray(),
            };

            int[][] leftSubIndices = new int[data.LeftSide.SubIndices.Count][];
            for (int i = 0; i < data.LeftSide.SubIndices.Count; i++)
            {
                leftSubIndices[i] = data.LeftSide.SubIndices[i].ToArray();
            }
            leftHalfMesh.SetIndices(leftSubIndices);

            // 右側のメッシュも同様に生成
            CutterMesh rightHalfMesh = new CutterMesh
            {
                Vertices    = data.RightSide.Vertices.ToArray(),
                Triangles   = data.RightSide.Triangles.ToArray(),
                Normals     = data.RightSide.Normals.ToArray(),
                UVs         = data.RightSide.UVs.ToArray(),
                BoneWeights = data.RightSide.BoneWeights.ToArray(),
            };

            int[][] rightSubIndices = new int[data.RightSide.SubIndices.Count][];
            for (int i = 0; i < data.RightSide.SubIndices.Count; i++)
            {
                rightSubIndices[i] = data.RightSide.SubIndices[i].ToArray();
            }
            rightHalfMesh.SetIndices(rightSubIndices);

            Debug.Log("cutter finish");

            // 左右のGameObjectの配列を返す
            return(new CutterMesh[] { leftHalfMesh, rightHalfMesh });
        }
Esempio n. 4
0
 public void SetTargetMesh(CutterMesh targetMesh)
 {
     _targetMesh = targetMesh;
 }