LoginSignup
13
8

More than 3 years have passed since last update.

[Unity] Oculus Goでメッシュカット(Mesh cut)

Last updated at Posted at 2018-08-19

概要

Oculus Goで3Dモデルをスパスパ切れたら楽しいだろうなぁと思って
色々調べながら作ったメッシュカットをUnityでするスクリプトです。

どこかの誰かの助けになればと簡単に公開できそうだったここに貼ってみてます。

以下のページなどを参考にさせていただきました。ありがとうございます。
https://qiita.com/edo_m18/items/31961cd19fd19e09b675
https://qiita.com/edo_m18/items/c8808f318f5abfa8af1e
http://ghoul-life.hatenablog.com/entry/2017/05/17/002422

<改良版はこちら>
https://qiita.com/ushikunv/items/eebe435bef24c027ed16

使い方

1. 切りたいオブジェクトに、RigidBody、MeshCutのスクリプトをくっつける
2. オブジェクトを切る刀などを用意して、colliderのIsTriggerをONにする。Cutterのスクリプトをくっつける
3. 切る

スクリプト

当方きちんとしたプログラミング教育を受けていないめちゃくちゃな素人なので
コードを書くルールとか分からず可読性皆無だったり頭悪いことしたりしてるのは許してください。
内容としてはメッシュを平面で2つに分割して切断面の頂点を作って表面を作ってます。
ただそれだけだとどんどん頂点が増えて重くなるので切断面の頂点を減らすような処理をしてます。

MeshCutのスクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshCut : MonoBehaviour {

    private MeshFilter attachedMeshFilter;
    private Mesh attachedMesh;
    private bool coliBool = false;
    public float delta = 0.00001f;
    public float skinWidth = 0.005f;

    float time0;

    void Start ()
    {
        Invoke ("BoolOn", 0.2f);
    }

    void BoolOn ()
    {
        attachedMeshFilter = GetComponent<MeshFilter> ();
        attachedMesh = attachedMeshFilter.mesh;
        coliBool = true;
    }

    public void Cut (Plane cutPlane)
    {
        if (coliBool == false) { return; }

        Vector3 p1, p2, p3;
        bool p1Bool, p2Bool, p3Bool;
        var uv1 = new List<Vector2> ();
        var uv2 = new List<Vector2> ();
        var vertices1 = new List<Vector3> ();
        var vertices2 = new List<Vector3> ();
        var triangles1 = new List<int> ();
        var triangles2 = new List<int> ();
        var normals1 = new List<Vector3> ();
        var normals2 = new List<Vector3> ();
        var crossVertices = new List<Vector3> ();

        for (int i = 0; i < attachedMesh.triangles.Length; i += 3) {
            p1 = transform.TransformPoint (attachedMesh.vertices [attachedMesh.triangles [i]]);
            p2 = transform.TransformPoint (attachedMesh.vertices [attachedMesh.triangles [i + 1]]);
            p3 = transform.TransformPoint (attachedMesh.vertices [attachedMesh.triangles [i + 2]]);

            p1Bool = cutPlane.GetSide (p1);
            p2Bool = cutPlane.GetSide (p2);
            p3Bool = cutPlane.GetSide (p3);

            if (p1Bool && p2Bool && p3Bool) {

                for (int k = 0; k < 3; k++) {
                    vertices1.Add (attachedMesh.vertices [attachedMesh.triangles [i + k]]);
                    uv1.Add (attachedMesh.uv [attachedMesh.triangles [i + k]]);
                    normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + k]]);
                    triangles1.Add (vertices1.Count - 1);
                }


            } else if (!p1Bool && !p2Bool && !p3Bool) {

                for (int k = 0; k < 3; k++) {
                    vertices2.Add (attachedMesh.vertices [attachedMesh.triangles [i + k]]);
                    uv2.Add (attachedMesh.uv [attachedMesh.triangles [i + k]]);
                    normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + k]]);
                    triangles2.Add (vertices2.Count - 1);
                }
            } else if ((p1Bool && !p2Bool && !p3Bool) || (!p1Bool && p2Bool && !p3Bool) || (!p1Bool && !p2Bool && p3Bool)) {
                Vector3 p, c1, c2;
                int n1, n2, n3;
                if (p1Bool) {
                    p = p1;
                    c1 = p2;
                    c2 = p3;
                    n1 = 0;
                    n2 = 1;
                    n3 = 2;

                } else if (p2Bool) {
                    p = p2;
                    c1 = p3;
                    c2 = p1;
                    n1 = 1;
                    n2 = 2;
                    n3 = 0;

                } else {
                    p = p3;
                    c1 = p1;
                    c2 = p2;
                    n1 = 2;
                    n2 = 0;
                    n3 = 1;

                }

                Vector3 cross1 = transform.InverseTransformPoint (p
                    + (-cutPlane.distance - Vector3.Dot (cutPlane.normal, p))
                    * (c1 - p) / Vector3.Dot (cutPlane.normal, c1 - p));
                Vector3 cross2 = transform.InverseTransformPoint (p
                    + (-cutPlane.distance - Vector3.Dot (cutPlane.normal, p))
                    * (c2 - p) / Vector3.Dot (cutPlane.normal, c2 - p));

                crossVertices.Add (cross1);
                crossVertices.Add (cross2);
                Vector2 cross1Uv = Vector2.Lerp (attachedMesh.uv [attachedMesh.triangles [i + n2]], attachedMesh.uv [attachedMesh.triangles [i + n1]], (transform.TransformPoint (cross1) - c1).magnitude / (p - c1).magnitude);
                Vector2 cross2Uv = Vector2.Lerp (attachedMesh.uv [attachedMesh.triangles [i + n3]], attachedMesh.uv [attachedMesh.triangles [i + n1]], (transform.TransformPoint (cross2) - c2).magnitude / (p - c2).magnitude);

                vertices1.Add (cross1);
                uv1.Add (cross1Uv);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles1.Add (vertices1.Count - 1);

                vertices1.Add (cross2);
                uv1.Add (cross2Uv);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles1.Add (vertices1.Count - 1);

                vertices1.Add (attachedMesh.vertices [attachedMesh.triangles [i + n1]]);
                uv1.Add (attachedMesh.uv [attachedMesh.triangles [i + n1]]);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles1.Add (vertices1.Count - 1);


                vertices2.Add (cross2);
                uv2.Add (cross2Uv);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles2.Add (vertices2.Count - 1);

                vertices2.Add (attachedMesh.vertices [attachedMesh.triangles [i + n2]]);
                uv2.Add (attachedMesh.uv [attachedMesh.triangles [i + n2]]);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n2]]);
                triangles2.Add (vertices2.Count - 1);

                vertices2.Add (attachedMesh.vertices [attachedMesh.triangles [i + n3]]);
                uv2.Add (attachedMesh.uv [attachedMesh.triangles [i + n3]]);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n3]]);
                triangles2.Add (vertices2.Count - 1);


                vertices2.Add (cross2);
                uv2.Add (cross2Uv);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles2.Add (vertices2.Count - 1);

                vertices2.Add (cross1);
                triangles2.Add (vertices2.Count - 1);
                uv2.Add (cross1Uv);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices2.Add (attachedMesh.vertices [attachedMesh.triangles [i + n2]]);
                uv2.Add (attachedMesh.uv [attachedMesh.triangles [i + n2]]);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n2]]);
                triangles2.Add (vertices2.Count - 1);

            } else if ((!p1Bool && p2Bool && p3Bool) || (p1Bool && !p2Bool && p3Bool) || (p1Bool && p2Bool && !p3Bool)) {
                Vector3 p, c1, c2;
                int n1, n2, n3;
                if (!p1Bool) {
                    p = p1;
                    c1 = p2;
                    c2 = p3;
                    n1 = 0;
                    n2 = 1;
                    n3 = 2;
                } else if (!p2Bool) {
                    p = p2;
                    c1 = p3;
                    c2 = p1;
                    n1 = 1;
                    n2 = 2;
                    n3 = 0;
                } else {
                    p = p3;
                    c1 = p1;
                    c2 = p2;
                    n1 = 2;
                    n2 = 0;
                    n3 = 1;
                }

                Vector3 cross1 = transform.InverseTransformPoint (p
                    + (-cutPlane.distance - Vector3.Dot (cutPlane.normal, p))
                    * (c1 - p) / Vector3.Dot (cutPlane.normal, c1 - p));
                Vector3 cross2 = transform.InverseTransformPoint (p
                    + (-cutPlane.distance - Vector3.Dot (cutPlane.normal, p))
                    * (c2 - p) / Vector3.Dot (cutPlane.normal, c2 - p));
                crossVertices.Add (cross1);
                crossVertices.Add (cross2);
                Vector2 cross1Uv = Vector2.Lerp (attachedMesh.uv [attachedMesh.triangles [i + n2]], attachedMesh.uv [attachedMesh.triangles [i + n1]], (transform.TransformPoint (cross1) - c1).magnitude / (p - c1).magnitude);
                Vector2 cross2Uv = Vector2.Lerp (attachedMesh.uv [attachedMesh.triangles [i + n3]], attachedMesh.uv [attachedMesh.triangles [i + n1]], (transform.TransformPoint (cross2) - c2).magnitude / (p - c2).magnitude);


                vertices2.Add (cross1);
                triangles2.Add (vertices2.Count - 1);
                uv2.Add (cross1Uv);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices2.Add (cross2);
                triangles2.Add (vertices2.Count - 1);
                uv2.Add (cross2Uv);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices2.Add (attachedMesh.vertices [attachedMesh.triangles [i + n1]]);
                uv2.Add (attachedMesh.uv [attachedMesh.triangles [i + n1]]);
                normals2.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);
                triangles2.Add (vertices2.Count - 1);


                vertices1.Add (cross2);
                triangles1.Add (vertices1.Count - 1);
                uv1.Add (cross2Uv);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices1.Add (attachedMesh.vertices [attachedMesh.triangles [i + n2]]);
                uv1.Add (attachedMesh.uv [attachedMesh.triangles [i + n2]]);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n2]]);
                triangles1.Add (vertices1.Count - 1);

                vertices1.Add (attachedMesh.vertices [attachedMesh.triangles [i + n3]]);
                uv1.Add (attachedMesh.uv [attachedMesh.triangles [i + n3]]);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n3]]);
                triangles1.Add (vertices1.Count - 1);



                vertices1.Add (cross2);
                triangles1.Add (vertices1.Count - 1);
                uv1.Add (cross2Uv);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices1.Add (cross1);
                triangles1.Add (vertices1.Count - 1);
                uv1.Add (cross1Uv);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n1]]);

                vertices1.Add (attachedMesh.vertices [attachedMesh.triangles [i + n2]]);
                uv1.Add (attachedMesh.uv [attachedMesh.triangles [i + n2]]);
                normals1.Add (attachedMesh.normals [attachedMesh.triangles [i + n2]]);
                triangles1.Add (vertices1.Count - 1);
            }
        }



        for (int i = 0; i < vertices1.Count; i += 3) {

            for (int j = i + 3; j < vertices1.Count; j += 3) {
                if (Vector3.Dot (Vector3.Cross (vertices1 [i + 1] - vertices1 [i], vertices1 [i + 2] - vertices1 [i + 1]).normalized, Vector3.Cross (vertices1 [j + 1] - vertices1 [j], vertices1 [j + 2] - vertices1 [j + 1]).normalized) > 1 - delta) {
                    for (int k = 0; k < 3; k++) {
                        int adj = 0;
                        if (k == 2) {
                            adj = -3;
                        }
                        if (Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [i + k]).normalized, (vertices1 [j + 1] - vertices1 [j]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [j+1]).normalized, (vertices1 [i+k] - vertices1 [j]).normalized) < delta - 1) {

                            if (Vector3.Dot ((vertices1 [i + numRep (2 + k)] - vertices1 [i + numRep (1 + k)]).normalized, (vertices1 [j] - vertices1 [j + 2]).normalized) > 1 - delta) {

                                vertices1.Add (vertices1 [i + k]);
                                uv1.Add (uv1 [i + k]);
                                normals1.Add (normals1 [i + k]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [j + 2]);
                                uv1.Add (uv1 [j + 2]);
                                normals1.Add (normals1 [j + 2]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices1 [i + k] - vertices1 [i + numRep (2 + k)]).normalized, (vertices1 [j + 2] - vertices1 [j + 1]).normalized) > 1 - delta) {

                                vertices1.Add (vertices1 [i + numRep (1 + k)]);
                                uv1.Add (uv1 [i + numRep (1 + k)]);
                                normals1.Add (normals1 [i + numRep (1 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);


                                vertices1.Add (vertices1 [j + 2]);
                                uv1.Add (uv1 [j + 2]);
                                normals1.Add (normals1 [j + 2]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;


                            }

                        } else if(Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [i + k]).normalized, (vertices1 [j + 2] - vertices1 [j+1]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [j+2]).normalized, (vertices1 [i+k] - vertices1 [j+1]).normalized) < delta - 1) {

                            if (Vector3.Dot ((vertices1 [i + numRep (2 + k)] - vertices1 [i + numRep (1 + k)]).normalized, (vertices1 [j + 1] - vertices1 [j]).normalized) > 1 - delta) {
                                vertices1.Add (vertices1 [i + k]);
                                uv1.Add (uv1 [i + k]);
                                normals1.Add (normals1 [i + k]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [j]);
                                uv1.Add (uv1 [j]);
                                normals1.Add (normals1 [j]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices1 [i + k] - vertices1 [i + numRep (2 + k)]).normalized, (vertices1 [j] - vertices1 [j + 2]).normalized) > 1 - delta) {
                                vertices1.Add (vertices1 [i + numRep (1 + k)]);
                                uv1.Add (uv1 [i + numRep (1 + k)]);
                                normals1.Add (normals1 [i + numRep (1 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);


                                vertices1.Add (vertices1 [j]);
                                uv1.Add (uv1 [j]);
                                normals1.Add (normals1 [j]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;


                            }


                        } else if(Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [i + k]).normalized, (vertices1 [j] - vertices1 [j+2]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices1 [i + numRep (1 + k)] - vertices1 [j]).normalized, (vertices1 [i+k] - vertices1 [j+2]).normalized) < delta - 1) {


                            if (Vector3.Dot ((vertices1 [i + numRep (2 + k)] - vertices1 [i + numRep (1 + k)]).normalized, (vertices1 [j + 2] - vertices1 [j + 1]).normalized) > 1 - delta) {

                                vertices1.Add (vertices1 [i + k]);
                                uv1.Add (uv1 [i + k]);
                                normals1.Add (normals1 [i + k]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [j + 1]);
                                uv1.Add (uv1 [j + 1]);
                                normals1.Add (normals1 [j + 1]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices1 [i + k] - vertices1 [i + numRep (2 + k)]).normalized, (vertices1 [j + 1] - vertices1 [j]).normalized) > 1 - delta) {

                                vertices1.Add (vertices1 [i + numRep (1 + k)]);
                                uv1.Add (uv1 [i + numRep (1 + k)]);
                                normals1.Add (normals1 [i + numRep (1 + k)]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.Add (vertices1 [i + numRep (2 + k)]);
                                uv1.Add (uv1 [i + numRep (2 + k)]);
                                normals1.Add (normals1 [i + numRep (2 + k)]);
                                triangles1.Add (vertices1.Count - 1);


                                vertices1.Add (vertices1 [j + 1]);
                                uv1.Add (uv1 [j + 1]);
                                normals1.Add (normals1 [j + 1]);
                                triangles1.Add (vertices1.Count - 1);

                                vertices1.RemoveRange (j, 3);
                                uv1.RemoveRange (j, 3);
                                normals1.RemoveRange (j, 3);
                                triangles1.RemoveRange (j, 3);

                                vertices1.RemoveRange (i, 3);
                                uv1.RemoveRange (i, 3);
                                normals1.RemoveRange (i, 3);
                                triangles1.RemoveRange (i, 3);

                                for (int l = 0; l < triangles1.Count; l++) {
                                    if (triangles1 [l] >= j) {
                                        triangles1 [l] -= 3;
                                    }
                                    if (triangles1 [l] >= i) {
                                        triangles1 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;


                            }



                        }
                    }


                }

            }


        }  



        for (int i = 0; i < vertices2.Count; i += 3) {

            for (int j = i + 3; j < vertices2.Count; j += 3) {
                if (Vector3.Dot (Vector3.Cross (vertices2 [i + 1] - vertices2 [i], vertices2 [i + 2] - vertices2 [i + 1]).normalized, Vector3.Cross (vertices2 [j + 1] - vertices2 [j], vertices2 [j + 2] - vertices2 [j + 1]).normalized) > 1 - delta) {
                    for (int k = 0; k < 3; k++) {
                        int adj = 0;
                        if (k == 2) {
                            adj = -3;
                        }
                        if (Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [i + k]).normalized, (vertices2 [j + 1] - vertices2 [j]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [j+1]).normalized, (vertices2 [i+k] - vertices2 [j]).normalized) < delta - 1) {

                            if (Vector3.Dot ((vertices2 [i + numRep (2 + k)] - vertices2 [i + numRep (1 + k)]).normalized, (vertices2 [j] - vertices2 [j + 2]).normalized) > 1 - delta) {

                                vertices2.Add (vertices2 [i + k]);
                                uv2.Add (uv2 [i + k]);
                                normals2.Add (normals2 [i + k]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [j + 2]);
                                uv2.Add (uv2 [j + 2]);
                                normals2.Add (normals2 [j + 2]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices2 [i + k] - vertices2 [i + numRep (2 + k)]).normalized, (vertices2 [j + 2] - vertices2 [j + 1]).normalized) > 1 - delta) {

                                vertices2.Add (vertices2 [i + numRep (1 + k)]);
                                uv2.Add (uv2 [i + numRep (1 + k)]);
                                normals2.Add (normals2 [i + numRep (1 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);


                                vertices2.Add (vertices2 [j + 2]);
                                uv2.Add (uv2 [j + 2]);
                                normals2.Add (normals2 [j + 2]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;


                            }

                        } else if(Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [i + k]).normalized, (vertices2 [j + 2] - vertices2 [j+1]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [j+2]).normalized, (vertices2 [i+k] - vertices2 [j+1]).normalized) < delta - 1) {

                            if (Vector3.Dot ((vertices2 [i + numRep (2 + k)] - vertices2 [i + numRep (1 + k)]).normalized, (vertices2 [j + 1] - vertices2 [j]).normalized) > 1 - delta) {
                                vertices2.Add (vertices2 [i + k]);
                                uv2.Add (uv2 [i + k]);
                                normals2.Add (normals2 [i + k]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [j]);
                                uv2.Add (uv2 [j]);
                                normals2.Add (normals2 [j]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices2 [i + k] - vertices2 [i + numRep (2 + k)]).normalized, (vertices2 [j] - vertices2 [j + 2]).normalized) > 1 - delta) {
                                vertices2.Add (vertices2 [i + numRep (1 + k)]);
                                uv2.Add (uv2 [i + numRep (1 + k)]);
                                normals2.Add (normals2 [i + numRep (1 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);


                                vertices2.Add (vertices2 [j]);
                                uv2.Add (uv2 [j]);
                                normals2.Add (normals2 [j]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;


                            }


                        } else if(Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [i + k]).normalized, (vertices2 [j] - vertices2 [j+2]).normalized) < delta - 1
                            &&Vector3.Dot ((vertices2 [i + numRep (1 + k)] - vertices2 [j]).normalized, (vertices2 [i+k] - vertices2 [j+2]).normalized) < delta - 1) {


                            if (Vector3.Dot ((vertices2 [i + numRep (2 + k)] - vertices2 [i + numRep (1 + k)]).normalized, (vertices2 [j + 2] - vertices2 [j + 1]).normalized) > 1 - delta) {

                                vertices2.Add (vertices2 [i + k]);
                                uv2.Add (uv2 [i + k]);
                                normals2.Add (normals2 [i + k]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [j + 1]);
                                uv2.Add (uv2 [j + 1]);
                                normals2.Add (normals2 [j + 1]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;



                            } else if (Vector3.Dot ((vertices2 [i + k] - vertices2 [i + numRep (2 + k)]).normalized, (vertices2 [j + 1] - vertices2 [j]).normalized) > 1 - delta) {

                                vertices2.Add (vertices2 [i + numRep (1 + k)]);
                                uv2.Add (uv2 [i + numRep (1 + k)]);
                                normals2.Add (normals2 [i + numRep (1 + k)]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.Add (vertices2 [i + numRep (2 + k)]);
                                uv2.Add (uv2 [i + numRep (2 + k)]);
                                normals2.Add (normals2 [i + numRep (2 + k)]);
                                triangles2.Add (vertices2.Count - 1);


                                vertices2.Add (vertices2 [j + 1]);
                                uv2.Add (uv2 [j + 1]);
                                normals2.Add (normals2 [j + 1]);
                                triangles2.Add (vertices2.Count - 1);

                                vertices2.RemoveRange (j, 3);
                                uv2.RemoveRange (j, 3);
                                normals2.RemoveRange (j, 3);
                                triangles2.RemoveRange (j, 3);

                                vertices2.RemoveRange (i, 3);
                                uv2.RemoveRange (i, 3);
                                normals2.RemoveRange (i, 3);
                                triangles2.RemoveRange (i, 3);

                                for (int l = 0; l < triangles2.Count; l++) {
                                    if (triangles2 [l] >= j) {
                                        triangles2 [l] -= 3;
                                    }
                                    if (triangles2 [l] >= i) {
                                        triangles2 [l] -= 3;
                                    }
                                }

                                j = 9999;
                                i = -3;
                                break;

                            }

                    }
                    }

                }

            }


        } 





        if (crossVertices.Count != 0) {

            for (int i = 0; i < crossVertices.Count; i += 2) {

                for (int k = 2; k < crossVertices.Count - i; k += 2) {

                    if (((System.Math.Abs (Vector3.Dot ((crossVertices [i] - crossVertices [i + k]).normalized, (crossVertices [i] - crossVertices [i + 1 + k]).normalized)) > 1 - delta))
                        && ((System.Math.Abs (Vector3.Dot ((crossVertices [i + 1] - crossVertices [i + k]).normalized, (crossVertices [i + 1] - crossVertices [i + 1 + k]).normalized)) > 1 - delta))
                        && ((System.Math.Abs (Vector3.Dot ((crossVertices [i] - crossVertices [i + 1]).normalized, (crossVertices [i + k] - crossVertices [i + 1 + k]).normalized)) > 1 - delta))
                        && ((System.Math.Abs (Vector3.Dot ((crossVertices [i] - crossVertices [i + 1 + k]).normalized, (crossVertices [i + k] - crossVertices [i + 1]).normalized)) > 1 - delta))) {
                        var value = System.Math.Max (Vector3.Distance (crossVertices [i], crossVertices [i + 1]), Vector3.Distance (crossVertices [i + k], crossVertices [i + k + 1]));
                        if (value >= Vector3.Distance (crossVertices [i], crossVertices [i + k])
                            && value >= Vector3.Distance (crossVertices [i], crossVertices [i + 1 + k])
                            && value >= Vector3.Distance (crossVertices [i + 1], crossVertices [i + k])
                            && value >= Vector3.Distance (crossVertices [i + 1], crossVertices [i + 1 + k])) {
                            if (Vector3.Distance (crossVertices [i], crossVertices [i + 1]) > Vector3.Distance (crossVertices [i + k], crossVertices [i + 1 + k])) {
                                crossVertices.RemoveRange (i + k, 2);
                            } else {
                                crossVertices.RemoveRange (i, 2);
                            }


                        } else {


                            if (Vector3.Distance (crossVertices [i], crossVertices [i + k]) > Vector3.Distance (crossVertices [i], crossVertices [i + 1 + k])) {
                                if (Vector3.Distance (crossVertices [i], crossVertices [i + k]) > Vector3.Distance (crossVertices [i + 1], crossVertices [i + k])) {
                                    crossVertices.Insert (i, crossVertices [i + k]);
                                    crossVertices.RemoveAt (i + 1 + k + 1);
                                    crossVertices.RemoveAt (i + k + 1);
                                    crossVertices.RemoveAt (i + 1 + 1);
                                } else {
                                    crossVertices.Insert (i, crossVertices [i + k]);
                                    crossVertices.RemoveAt (i + 1 + k + 1);
                                    crossVertices.RemoveAt (i + k + 1);
                                    crossVertices.RemoveAt (i + 1);
                                }
                            } else {
                                if (Vector3.Distance (crossVertices [i], crossVertices [i + 1 + k]) > Vector3.Distance (crossVertices [i + 1], crossVertices [i + 1 + k])) {
                                    crossVertices.Insert (i, crossVertices [i + 1 + k]);
                                    crossVertices.RemoveAt (i + 1 + k + 1);
                                    crossVertices.RemoveAt (i + k + 1);
                                    crossVertices.RemoveAt (i + 1 + 1);
                                } else {
                                    crossVertices.Insert (i, crossVertices [i + 1 + k]);
                                    crossVertices.RemoveAt (i + 1 + k + 1);
                                    crossVertices.RemoveAt (i + k + 1);
                                    crossVertices.RemoveAt (i + 1);
                                }
                            }

                        }

                        i = -2;
                        break;

                    }

                }
            }



            Vector3 center = new Vector3 ();
            foreach (var v in crossVertices) {
                center += v;
            }
            center /= crossVertices.Count;


            for (int i = 0; i < crossVertices.Count; i += 2) {
                if (Vector3.Dot (Vector3.Cross (transform.TransformPoint (crossVertices [i]) - transform.TransformPoint (center), transform.TransformPoint (crossVertices [i + 1]) - transform.TransformPoint (crossVertices [i])), cutPlane.normal) <= 0) {

                    Vector3 nor = Vector3.Cross (transform.TransformPoint (crossVertices [i]) - transform.TransformPoint (center), transform.TransformPoint (crossVertices [i + 1]) - transform.TransformPoint (crossVertices [i])).normalized;

                    normals1.Add (nor);
                    normals1.Add (nor);
                    normals1.Add (nor);
                    normals2.Add (-nor);
                    normals2.Add (-nor);
                    normals2.Add (-nor);



                    vertices1.Add (center);
                    uv1.Add (new Vector2 (0, 0));
                    triangles1.Add (vertices1.Count - 1);

                    vertices1.Add (crossVertices [i]);
                    triangles1.Add (vertices1.Count - 1);
                    uv1.Add (new Vector2 (0, 0));

                    vertices1.Add (crossVertices [i + 1]);
                    uv1.Add (new Vector2 (0, 0));
                    triangles1.Add (vertices1.Count - 1);



                    vertices2.Add (crossVertices [i]);
                    triangles2.Add (vertices2.Count - 1);
                    uv2.Add (new Vector2 (0, 0));

                    vertices2.Add (center);
                    uv2.Add (new Vector2 (0, 0));
                    triangles2.Add (vertices2.Count - 1);

                    vertices2.Add (crossVertices [i + 1]);
                    uv2.Add (new Vector2 (0, 0));
                    triangles2.Add (vertices2.Count - 1);

                } else {

                    Vector3 nor = -Vector3.Cross (transform.TransformPoint (crossVertices [i]) - transform.TransformPoint (center), transform.TransformPoint (crossVertices [i + 1]) - transform.TransformPoint (crossVertices [i])).normalized;

                    normals1.Add (nor);
                    normals1.Add (nor);
                    normals1.Add (nor);
                    normals2.Add (-nor);
                    normals2.Add (-nor);
                    normals2.Add (-nor);



                    vertices1.Add (crossVertices [i]);
                    triangles1.Add (vertices1.Count - 1);
                    uv1.Add (new Vector2 (0, 0));

                    vertices1.Add (center);
                    uv1.Add (new Vector2 (0, 0));
                    triangles1.Add (vertices1.Count - 1);

                    vertices1.Add (crossVertices [i + 1]);
                    uv1.Add (new Vector2 (0, 0));
                    triangles1.Add (vertices1.Count - 1);


                    vertices2.Add (center);
                    uv2.Add (new Vector2 (0, 0));
                    triangles2.Add (vertices2.Count - 1);

                    vertices2.Add (crossVertices [i]);
                    uv2.Add (new Vector2 (0, 0));
                    triangles2.Add (vertices2.Count - 1);

                    vertices2.Add (crossVertices [i + 1]);
                    uv2.Add (new Vector2 (0, 0));
                    triangles2.Add (vertices2.Count - 1);


                }
            }
        }


        GameObject obj = new GameObject ("cut obj", typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider), typeof(Rigidbody), typeof(MeshCut));
        var mesh = new Mesh ();
        mesh.vertices = vertices1.ToArray ();
        mesh.triangles = triangles1.ToArray ();
        mesh.uv = uv1.ToArray ();
        mesh.normals = normals1.ToArray ();
        obj.GetComponent<MeshFilter> ().mesh = mesh;
        obj.GetComponent<MeshRenderer> ().materials = GetComponent<MeshRenderer> ().materials;
        obj.GetComponent<MeshCollider> ().sharedMesh = mesh;
        obj.GetComponent<MeshCollider> ().inflateMesh = true;
        obj.GetComponent<MeshCollider> ().skinWidth = skinWidth;
        obj.GetComponent<MeshCollider> ().convex = true;
        obj.GetComponent<MeshCollider> ().material = GetComponent<Collider> ().material;
        obj.transform.position = transform.position;
        obj.transform.rotation = transform.rotation;
        obj.transform.localScale = transform.localScale;
        obj.GetComponent<Rigidbody> ().velocity = GetComponent<Rigidbody> ().velocity;
        obj.GetComponent<Rigidbody> ().angularVelocity = GetComponent<Rigidbody> ().angularVelocity;
        obj.GetComponent<MeshCut>().skinWidth = skinWidth;
        obj.GetComponent<MeshCut>().Start();

        GameObject obj2 = new GameObject ("cut obj", typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider), typeof(Rigidbody), typeof(MeshCut));

        var mesh2 = new Mesh ();
        mesh2.vertices = vertices2.ToArray ();
        mesh2.triangles = triangles2.ToArray ();
        mesh2.uv = uv2.ToArray ();
        mesh2.normals = normals2.ToArray ();
        obj2.GetComponent<MeshFilter> ().mesh = mesh2;
        obj2.GetComponent<MeshRenderer> ().materials = GetComponent<MeshRenderer> ().materials;
        obj2.GetComponent<MeshCollider> ().sharedMesh = mesh2;
        obj2.GetComponent<MeshCollider> ().inflateMesh = true;
        obj2.GetComponent<MeshCollider> ().skinWidth = skinWidth;
        obj2.GetComponent<MeshCollider> ().convex = true;
        obj2.GetComponent<MeshCollider> ().material = GetComponent<Collider> ().material;
        obj2.transform.position = transform.position;
        obj2.transform.rotation = transform.rotation;
        obj2.transform.localScale = transform.localScale;
        obj2.GetComponent<Rigidbody> ().velocity = GetComponent<Rigidbody> ().velocity;
        obj2.GetComponent<Rigidbody> ().angularVelocity = GetComponent<Rigidbody> ().angularVelocity;
        obj2.GetComponent<MeshCut>().skinWidth = skinWidth;
        obj2.GetComponent<MeshCut>().Start();

        Destroy (gameObject);

    }

    int numRep (int i)
    {
        if (i % 3 == 0) {
            return 0;
        } else if (i % 3 == 1) {
            return 1;
        } else if (i % 3 == 2) {
            return 2;
        } else {
            return 0;
        }
    }

}

Cutterのスクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Cutter : MonoBehaviour {

    private Vector3 prePos = Vector3.zero;
    private Vector3 prePos2 = Vector3.zero;

    // Update is called once per frame
    void FixedUpdate ()
    {
        prePos = prePos2;
        prePos2 = transform.position;
    }

    // このコンポーネントを付けたオブジェクトのCollider.IsTriggerをONにすること!
    void OnTriggerEnter(Collider other)
    {
        var meshCut = other.gameObject.GetComponent<MeshCut>();
        if (meshCut == null) { return; }

        var cutPlane = new Plane (Vector3.Cross(transform.forward.normalized, prePos - transform.position).normalized, transform.position);
        meshCut.Cut(cutPlane);
    }

}

最後に

うまくいかない時はdeltaの値をいじったりするとよいかも。
Oculus Goでも割と軽く動くと思います、切りすぎると重くなりますが。
誰か遊んでくれて改良してくれたらうれしいです。

修正改良等いただきました。ありがとうございます。

13
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8