0

I am implementing triangle removal of a mesh by using ray cast. It removes the triangles from the moves that the ray cast is hitting it, but the problem is when I am trying to remove the triangles, it removes the back part of the mesh not the front, and only when I am hitting with ray cast from inside of the mesh. I am not sure what can be the problem, any help and guidance will be really appreciated. I have attached the picture.

In the imaged uploaded, the scene view is flipped down and the game view shows the object that cast ray is in middle:

Following is my implementation:

using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Numerics;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;
using Vector4 = UnityEngine.Vector4;


public class RemoveTriangle : MonoBehaviour
{
    [Header("Game Object")][Tooltip("The game object that will be removed its triangles")]
    public GameObject spherePrefab;
    // Better to reference those already in the Inspector
    [Header("Mesh Files to Load")]
    [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private MeshFilter meshFilter;
    [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private MeshRenderer meshRenderer;
    [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private MeshCollider meshCollider;
    //[SerializeField] [Range(1.0f, 3.0f)] public float raycastSize = 1.0f;
    [Header("Origin and Target objects")]
    [Tooltip("Drag and drop the origin and target objects")]public Transform SelectOrigin;
    [Tooltip("Drag and drop the origin and target objects")]public MeshFilter SelectTarget;
    [Header("Raycast Distance")][Tooltip("The distance of the raycast")]
    [SerializeField][Range(0.1f,20.0f)]public float MaxDistance = 10f;
    private Mesh mesh;
    
    
    
    private void Awake()
    {
        MeshProperties();

    }

    private void Update()
    {
        
        DeleteTriangle();

    }
    
    void MeshProperties()
    {// Get the mesh from the mesh filter
        if (!meshFilter) meshFilter = GetComponent<MeshFilter>();
        
        if (!meshRenderer) meshRenderer = GetComponent<MeshRenderer>();
        if (!meshCollider) meshCollider = GetComponent<MeshCollider>();


        mesh = meshFilter.mesh;
    }// MeshProperties

    void DeleteTriangle()
    {//raycast from mouse position
        if (Input.GetKey(KeyCode.C))
        {//raycast from mouse position
            
            Ray ray = new Ray(SelectOrigin.position, SelectOrigin.forward);
            RaycastHit hit;
            

            if (Physics.Raycast(ray, out hit, MaxDistance))
            {//if raycast hits a triangle
                Debug.DrawRay(SelectOrigin.position,
                            SelectTarget.transform.position - SelectOrigin.position, 
                             Color.red);
                Debug.Log("Triangle Removed at: " + hit.point + "/" + hit.triangleIndex + "/" + hit.normal);

                //cube.transform.position = hit.point;

                // Get current vertices, triangles, uvs,tangents and normals of the mesh
                Vector3[] vertices = mesh.vertices;
                Vector2[] uv = mesh.uv;
                Vector4[] tangents = mesh.tangents;
                Vector3[] normals = mesh.normals;

                int[] triangles = mesh.triangles;


                // Get the vert indices for this triangle
                int vertIndex_1 = triangles[hit.triangleIndex * 3 + 0];
                int vertIndex_2 = triangles[hit.triangleIndex * 3 + 1];
                int vertIndex_3 = triangles[hit.triangleIndex * 3 + 2];

                // Get the vertices for this triangle
                var vert_1 = vertices[vertIndex_1];
                var vert_2 = vertices[vertIndex_2];
                var vert_3 = vertices[vertIndex_3];

                // Get the uv for this triangle
                var uv_1 = uv[vertIndex_1];
                var uv_2 = uv[vertIndex_2];
                var uv_3 = uv[vertIndex_3];

                //Get the Normals for this triangle
                var normal_1 = mesh.normals[vertIndex_1];
                var normal_2 = mesh.normals[vertIndex_2];
                var normal_3 = mesh.normals[vertIndex_3];

                //Get Tangents for this triangle
                Vector4 tangent_1 = mesh.tangents[vertIndex_1];
                Vector4 tangent_2 = mesh.tangents[vertIndex_2];
                Vector4 tangent_3 = mesh.tangents[vertIndex_3];




                // Get the positions for the vertices
                var vertPos_1 = vertices[vertIndex_1];
                var vertPos_2 = vertices[vertIndex_2];
                var vertPos_3 = vertices[vertIndex_3];

                // Get the center of the triangle
                var center = (vertPos_1 + vertPos_2 + vertPos_3) / 3;



                // Now for all three vertices we first check if any other triangle if using it
                // by simply count how often the indices are used in the triangles list
                var verticesOccur_1 = 0;
                var verticesOccur_2 = 0;
                var verticesOccur_3 = 0;


                for (var i = 0; i < triangles.Length; i++)
                {
                    if (triangles[i] == vertIndex_1)
                        verticesOccur_1++;
                    if (triangles[i] == vertIndex_2)
                        verticesOccur_2++;
                    if (triangles[i] == vertIndex_3)
                        verticesOccur_3++;
                }//end for

                // Remove the vertices
                if (verticesOccur_1 == 1)
                    vertices[vertIndex_1] = Vector3.zero;
                if (verticesOccur_2 == 1)
                    vertices[vertIndex_2] = Vector3.zero;
                if (verticesOccur_3 == 1)
                    vertices[vertIndex_3] = Vector3.zero;

                // Remove the uv
                if (verticesOccur_1 == 1)
                    uv[vertIndex_1] = Vector2.zero;
                if (verticesOccur_2 == 1)
                    uv[vertIndex_2] = Vector2.zero;
                if (verticesOccur_3 == 1)
                    uv[vertIndex_3] = Vector2.zero;

                // Remove the normals
                if (verticesOccur_1 == 1)
                    mesh.normals[vertIndex_1] = Vector3.zero;
                if (verticesOccur_2 == 1)
                    mesh.normals[vertIndex_2] = Vector3.zero;
                if (verticesOccur_3 == 1)
                    mesh.normals[vertIndex_3] = Vector3.zero;

                // Remove the tangents
                if (verticesOccur_1 == 1)
                    mesh.tangents[vertIndex_1] = Vector4.zero;
                if (verticesOccur_2 == 1)
                    mesh.tangents[vertIndex_2] = Vector4.zero;
                if (verticesOccur_3 == 1)
                    mesh.tangents[vertIndex_3] = Vector4.zero;

                
                //fix the triangles
                //for (var i = 0; i < triangles.Length; i++)
                //{
                //if (triangles[i] == vertIndex_1) triangles[i] = 0;
                // (triangles[i] == vertIndex_2) triangles[i] = 0;
                //if (triangles[i] == vertIndex_3) triangles[i] = 0;
                //}]

                // Find the intersecting triangles by checking if the ray intersects with their vertices
                //var intersectingTriangles = new List<int>();

                /* for (var i = 0; i < triangles.Length; i += 3)
                 {
                     var triangleVertIndex_1 = triangles[i + 0];
                     var triangleVertIndex_2 = triangles[i + 1];
                     var triangleVertIndex_3 = triangles[i + 2];
                     
                     var triangleVertPos_1 = vertices[triangleVertIndex_1];
                     var triangleVertPos_2 = vertices[triangleVertIndex_2];
                     var triangleVertPos_3 = vertices[triangleVertIndex_3];
                     
                    
                 }*/

                // Remove the triangles and update the mesh
                triangles[hit.triangleIndex * 3] = 0;
                triangles[hit.triangleIndex * 3 + 1] = 0;
                triangles[hit.triangleIndex * 3 + 2] = 0;

                //update the mesh with the new vertices, uv, normals and tangents
                mesh.vertices = vertices;
                mesh.uv = uv;
                mesh.tangents = tangents;
                mesh.normals = normals;
                
                //update the tirangles
                mesh.triangles = triangles;
                
                // Recalculate the normals
                mesh.RecalculateNormals();
                
                // Recalculate the tangents
                mesh.RecalculateTangents();
                
                // Recalculate the bounds
                mesh.RecalculateBounds();
            }//end of if
            else
            {

                Debug.Log("No Triangle to remove" + hit.point);
                
            }//end of if hit.triangleIndex
            
        }//end of remove triangle
        
    }//end of class
    
}//end of class

I tried to change the setting of mesh, but it did not give me a good result. I feel like there is a problem with the mesh, but I cannot understand what the problem is.

aybe
  • 15,516
  • 9
  • 57
  • 105
  • 1
    Your problem sounds as if the winding order is wrong for the collider, i.e. CW vs CCW. But it could be something else as well. – aybe Jan 11 '23 at 10:39
  • Is there any way or resources that can help with that? Because I have no idea what it is and how to fix it. I will appreciate it! – user20980680 Jan 11 '23 at 12:47
  • Try reverse the order of vertices in triangles, e.g. ABC, DEF to CBA, FED, etc and probably its normals as well. Even better, try open it in Blend and do that from here so you can commit the changes instead of doing it by code. Other than that, check that the ray you're casting is in the good direction, use gizmos to draw relevant debug stuff. – aybe Jan 11 '23 at 22:51

0 Answers0