/// <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); }
public MeshCutData(CutterMesh victimMesh, CutterPlane blade) { VictimMesh = victimMesh; LeftSide.SetTargetMesh(victimMesh); RightSide.SetTargetMesh(victimMesh); Blade = blade; }
/// <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 }); }
public void SetTargetMesh(CutterMesh targetMesh) { _targetMesh = targetMesh; }