13
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?