- Home /
Problem creating submeshes based on raycast.
Hi everybody. So I've been stuck on this problem for days now. So I have a mesh imported from Blender (picture down below) that will act as the game map. What I want to do at the moment is: - Shoot a raycast into the scene and get the triangle index with hit.triangleIndex - I then calculate the longest edge of this triangle to know which 2 vertices are next to the triangle that will form a square. - Then I call another method that takes this two vertices and finds the indices of them in the vertices array. - A call to another method that finds the index of the triangle next to the one shot with raycast. - Call to a method passing the 2 indices in the triangle list forming a square. This method is called highlight square.
Now if I wanted to delete the square I selected, then there is no problem, but if I decide to modify the a bit to move the selected square to a different submesh I run into all kinds of weird problems. I have tested multiple solutions but it breaks everytime, you name it I've seen it (freezing, outOfMemory, failed setting triangles, out of bounds, it works for the first square but when I click on another one a random square gets selected etc.).
So please guys help me out in figuring this out, if it's too complicated can you guys show me how to do this with combine meshes instead (basically separate the square I select from the mesh and then combine it to a different submesh)? Maybe it has to do with my code, maybe with the vertices array being messed up, I have no clue.
Here is the code, pardon the mess, I've changed it more than 20 times.
![using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class cutHole : MonoBehaviour {
private int[] triangles;
private Vector3[] vertices;
private int[] oldTriangles;
private int[] newTriangles;
private Mesh mesh;
public Material[] mats;
private Renderer rend;
private List<int> testL;
// Use this for initialization
void Start () {
mesh = transform.GetComponent<MeshFilter>().mesh;
triangles = mesh.triangles;
vertices = mesh.vertices;
oldTriangles = triangles;
rend = GetComponent<Renderer>();
testL = new List<int>();
}
void highlightSquare (int index1, int index2)
{
int i = 0;
int j = 0;
Debug.Log(index1);
Debug.Log(index2);
Debug.Log(oldTriangles.Length);
Debug.Log(vertices.Length);
newTriangles = new int[oldTriangles.Length - 6];
while (j < oldTriangles.Length)
{
if (j != index1 * 3 && j != index2 * 3)
{
newTriangles[i++] = oldTriangles[j++];
newTriangles[i++] = oldTriangles[j++];
newTriangles[i++] = oldTriangles[j++];
}
else
{
testL.Add(j++);
testL.Add(j++);
testL.Add(j++);
//j += 3;
}
}
mesh.subMeshCount = 2;
foreach (int h in testL)
{
Debug.Log(h);
}
Debug.Log(vertices.Length);
Debug.Log(vertices.Length);
mesh.SetTriangles(newTriangles, 1);
//mesh.SetTriangles(testL, 0);
oldTriangles = newTriangles;
triangles = oldTriangles;
rend.materials = mats;
Debug.Log(mesh.subMeshCount);
}
/*void deleteSquare(int index1, int index2)
{
//Destroy(this.gameObject.GetComponent<MeshCollider>());
//Mesh mesh = transform.GetComponent<MeshFilter>().mesh;
//int[] oldTriangles = triangles;
//int[] newTriangles = new int[triangles.Length-6];
int i = 0;
int j = 0;
while (j < triangles.Length)
{
if(j != index1*3 && j != index2*3)
{
newTriangles[i++] = oldTriangles[j++];
newTriangles[i++] = oldTriangles[j++];
newTriangles[i++] = oldTriangles[j++];
}
else
{
j += 3;
}
}
triangles = newTriangles;
oldTriangles = triangles;
transform.GetComponent<MeshFilter>().mesh.triangles = newTriangles;
this.gameObject.AddComponent<MeshCollider>();
}*/
int findVertex(Vector3 v)
{
for(int i = 0; i < vertices.Length; i++)
{
if(vertices[i] == v)
return i;
}
Debug.Log("Not found");
return -1;
}
int findTriangle(Vector3 v1, Vector3 v2, int notTriIndex)
{
int i = 0;
int j = 0;
int found = 0;
while (j < triangles.Length)
{
if(j/3 != notTriIndex)
{
if(vertices[triangles[j]] == v1 && (vertices[triangles[j+1]] == v2 || vertices[triangles[j+2]] == v2))
return j/3;
else if(vertices[triangles[j]] == v2 && (vertices[triangles[j+1]] == v1 || vertices[triangles[j+2]] == v1))
return j/3;
else if(vertices[triangles[j+1]] == v2 && (vertices[triangles[j]] == v1 || vertices[triangles[j+2]] == v1))
return j/3;
else if(vertices[triangles[j+1]] == v1 && (vertices[triangles[j]] == v2 || vertices[triangles[j+2]] == v2))
return j/3;
}
j+=3;
}
return -1;
}
// Update is called once per frame
void Update ()
{
//Debug.Log(mesh.subMeshCount);
if(Input.GetMouseButtonDown(0))
{
Debug.Log(vertices.Length);
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, 1000.0f))
{
int hitTri = hit.triangleIndex;
//get neighbour
Vector3 p0 = vertices[triangles[hitTri * 3 + 0]];
Vector3 p1 = vertices[triangles[hitTri * 3 + 1]];
Vector3 p2 = vertices[triangles[hitTri * 3 + 2]];
float edge1 = Vector3.Distance(p0,p1);
float edge2 = Vector3.Distance(p0,p2);
float edge3 = Vector3.Distance(p1,p2);
Vector3 shared1;
Vector3 shared2;
if (edge1 > edge2 && edge1 > edge3)
{
shared1 = p0;
shared2 = p1;
}
else if(edge2 > edge1 && edge2 > edge3)
{
shared1 = p0;
shared2 = p2;
}
else
{
shared1 = p1;
shared2 = p2;
}
int v1 = findVertex(shared1);
int v2 = findVertex(shared2);
//deleteSquare(hitTri,findTriangle(vertices[v1], vertices[v2], hitTri));
highlightSquare(hitTri, findTriangle(vertices[v1], vertices[v2], hitTri));}
}
}
}][1]
[1]: /storage/temp/146057-map-unity.png
Your answer
Follow this Question
Related Questions
Problem Creating a 2D Mesh 1 Answer
Quick way to get touching triangles? 0 Answers
How to find connected mesh triangles? 2 Answers
Mesh triangles and vertices, searching for adjacent triangle 1 Answer